Figure 1: Mission Planner waypoints and telemetry track after 3 spline circuits |
I wanted my ArduCopter to fly smooth continuous curves between waypoints for some nicer aerial video, so I coded up this SplineNav class. Each spline segment is a cubic polynomial curve defined in 3D space, with 1st and 2nd derivatives continuous wherever two segments meet at a waypoint. This gives a nice smooth transition between curve segments during flight (Figure 1). It also saves time and battery, since abrupt speed and direction changes are avoided.
Figure 2: Autopilot logged track after 3 spline circuits |
The SplineNav class, like CIRCLE mode, calls the loiter controller, which is what allows it to precisely control position along the curve using GPS and inertial navigation (thanks to the brand new ArduCopter 3.0 firmware). Unlike CIRCLE mode, in SplineNav the autopilot takes full control of setting altitude as well, so it can fly complex 3D curves. However, it also references your WPNAV_SPEED, WPNAV_SPEED_DN, and WPNAV_SPEED_UP parameter settings to avoid flying too fast, or climbing or descending too quickly.
For this video I wanted a slightly more wild ride, so I increased my WPNAV_SPEED_DN to 250 cm/s, and WPNAV_SPEED_UP to 350 cm/s. I left WPNAV_SPEED at 500 cm/s for now, but will try increasing it later. Figure 2 shows the 3D track in Google Earth. If you reduce these UP/DN speed parameters you will get the same 3D track for these waypoints, but at the steep up and down locations SplineNav will reduce its travel speed along the 3D curve.
Video
I shot this SplineNav demonstration video with my ArduPhantom. The GoPro is mounted on a Hummer 2-axis brushless gimbal designed for DJI Phantom.
Source Code
Here's the source code for developers and brave testers to test and suggest fixes and improvements. There's a .PDE file and an .H file, both of which go in your ArduCopter 3.0 sketch folder:
SplineNav.h
SplineNav.pde
Follow the directions in the SplineNav Readme to make the ArduCopter 3.0 code call SplineNav. Then compile with the special ArduPilot version of the Arduino IDE, and upload to your copter. Set your waypoints with Mission Planner, or with the channel 7 switch, and go test out SplineNav.
Warnings
Comments
So I did manage to get rid of most of that SplineNav yaw jitter. Although now that the yaw jitter is pretty much gone, the remaining roll and pitch jitter looks much more obvious in the video.
SplineNav 0.3: http://www.diydrones.com/profiles/blogs/new-splinenav-0-3-smoother-...
Ah, that's very very gooood....Awesome !
New SplineNav version 0.2 now available for bold testers: https://github.com/mavbot/SplineNav
And I did manage to get it to exceed 60 km/h as I predicted, although it was on the downwind leg: http://diydrones.com/profiles/blogs/new-splinenav-version-0-2-on-a-...
Yes, these are basically bezier curves where the derivative at each waypoint is set as the difference between previous and next waypoints, divided by some tension parameter. You could use the same algorithm but with just a slight change to allow for adjustable handles, however you probably wouldn't want the user to be able to adjust the derivative to be different on either side of the waypoint, because then the aircraft would jerk as it went over the waypoint instead of flying smoothly. Allowing the user to adjust tension and direction at each waypoint in a way that it remained the same on each side would make sense, but someone would need to build a GUI to do that, which might take some work, since these curves are in 3D space.
For my own use at least, I've found just being able to adjust tension globally works pretty well to get the curve how I want it; so far I haven't found the need to make adjustments at each waypoint. Although I can see where there could be situations where that might be a useful feature.
As for aircraft performance, it uses the user-configured parameters in Mission Planner for max speed, max acceleration, max climb rate, and descent rate to place limits on the speed and acceleration as it flies the curve. It also slows down target speed automatically as altitude or position lags target, which makes it safe to fly fast into headwinds or if aircraft power is otherwise lower than expected. (Note: this is with the recently updated SplineNav code, to be released soon).
It's not perfect, since we don't really have the computing power available to do look-ahead processing of the spline curve, but in my testing it works quite well. I will post another video soon, hopefully with spline segments exceeding 60 km/h.
That's really impressive. Would you be kind enough to describe your approach/algorithm here? Does the algorithm rely heavily on knowing the performance of the aircraft? Have you thought about Bezier curves with adjustable handles?
Hi Olivier, that's a great idea, it's good to know we'll be able to test a mix of spline segments and straight lines quite easily then. Maybe I'll implement that once I finish these other SplineNav improvements I'm currently working on thanks to suggestions from some of the devs. This is really exciting stuff!
I'm not sure about that but i think we have a 8 bits option free for nav commands.
See here :
http://copter.ardupilot.com/wiki/common-mavlink-commands/
Actually we are using parameter 1 for Waypoint delay, so that it is possible to stop a few seconds at selected waypoints. If you put 0, then there is no stop on the waypoint.
This delay field could be used as well for defining spline waypoints, using for example the value 255.
Could be a temporary trick to implement this without Mission Planner modifications.
Sounds like the devs are planning a new waypoint controller anyway, so maybe this is something that could be added in the not-so-distant future.
I'm glad we're on the same wavelength David! If there's a wishlist for official Arducopter features, that should definitely go on it.