Spiraling Under Control

One of the staples of fixed wing autopilots is the circle hold.  A circle hold is the closest thing you can get to a pause button with a vehicle that must be in constant forward motion to stay aloft.  There are a few hidden challenges in the task, including wind compensation and some unexpected coupling that can lead to weird looking oscillations if not handled well.  People have been doing circle holds with UAV’s for a long long time, so I don’t bring anything new to the table, but it is always fun to play, err I mean experiment.

Circles

What happens if you periodically move the center of your circle (maybe every 5 mintues) to a new location, hold for a while, move the circle center again, circle for a while, and repeat?  Well short answer is you end up with a bunch of circles, but if you are strategic in the placement of the circle center, some pretty patterns can begin to emerge.  To add visual interest we can also change the circle speed when we move the center of the circle.  Increasing the circling speed, increases the circle radius.

fgfs-screen-001

What if each time we move the circle center point, we move it by a fixed angle (let’s try 30 degrees), and increase the offset distance by a little bit, and also in crease the airspeed by a 1 kt?  An interesting spiral pattern begins to emerge.  From the original starting point, each circle is a bit bigger than the one before, and also a bit further away.  A spiral pattern begins to emerge.

fgfs-screen-002

A flight simulator isn’t encumbered by battery or fuel limitations, so what happens if we let this run for a long time?  The spiral pattern continues to develop and grow.fgfs-screen-003

Spirals aren’t that big of a deal of course.  20 minutes of python coding could produce some far fancier spirals.  What interests me is how the patterns are produced … this is the flight track of a simulated UAV and that makes it a bit more challenging and fun.

Continuous Spirals

What happens if we fly a basic circle hold, but instead of changing the circle center point every 5 minutes, we continually move the center target of the circle in sweeping spiral pattern?  We would get something that looks a bit like a stretched spring viewed from a bit of an angle.

At the beginning of the pattern, the airspeed is set to 25 kts.  The radius (not of the circle hold but of the spiral) is set to 0.1 nm.   Each second the position is swept forward 0.125 degrees.  This means the spiral pattern sweeps forward 7.5 degrees per minute, or 450 degrees per hour.  The airspeed and spiral radius are also increased by a tiny bit each second.  The next picture shows the pattern after a bit more than an hour of flight.

fgfs-screen-004

After about 5 hours of flight we get the next picture:

fgfs-screen-006

And if we let the simulation run over night and zoom out the map a couple steps, we get:

fgfs-screen-007

A Few More Details

All these patterns were produced by the flight track of a UAV.  That means we aren’t just plotting mathematical functions, but instead are combatting wind and physics to produce these patterns.  A complex system of sensors, attitude estimation, control theory, navigation and planning blends together to produce the end result.

Simulation vs. Reality

All of this was flown in the FlightGear.org flight simulator.  However, there is a much stronger tie to reality than might first appear.  FlightGear is the ‘stand in’ for reality.  However all the sensor data is sent externally to the “avior” autopilot running in “software in the loop” testing mode.  The avior autopilot code sends all the raw sensor information (simulated IMU and simulated GPS) into a 15 state kalman filter to estimate the actual roll, pitch, and yaw.  It would be possible to cheat and use the simulators exact roll, pitch, and yaw, but the “avior” can’t cheat in real life (because this information isn’t directly available) so it faithfully estimates these values in simulation just like it must in the real aircraft.

The roll, pitch, & yaw estimates are then passed to flight control system and compared with target values for basic flight control and navigation.  The “avior” autopilot computes control surface deflections to eliminate the error between target speed, and attitude vs. actual speed and attitude.

Finally, these control surface positions are sent back to FlightGear which then computes the flight physics based on where the avior moves the control surfaces and throttle.  FlightGear computes new gyro, accelerometer, and gps sensor values, sends them to the avior autopilot, and the process repeats.

In this way we can test the “avior” autopilot quite thoroughly using the simulation.  The avior thinks it’s really flying, it receives realistic sensor data, drives control surfaces as if they were real servos, and the simulator responds realistically.  Really the only part of the avior not being thoroughly exercised is the specific code that reads the real world sensors and the specific code that drives the real world servos.

Wind

At first glance, the job of flying a circle hold around a fixed center point amounts to holding a fixed bank angle.  There is a relationship between airspeed, bank angle, and turning radius, so we just need to work out these numbers and we can fly any circle of any radius at any speed, simply by computing the required bank angle.

But things get a bit more complicated than this because we need to adjust our actual heading and bank angle to compensate for drifting inside or outside the target circle radius.  And there is this whole business of figuring out how to smoothly enter the circle pattern from any starting position and heading inside or outside the circle.

I’ll skip over the boring details (ask if you are curious) but along with all the other things that must be accounted for, the real world almost always has a little (or a lot) of wind.  Flying up wind, small heading changes of the aircraft can yield large changes in your ground track heading.  Imagine a worst case scenario where you are flying at 30 kts, exactly into a 30 kt head wind.  You are hoving relative to the ground.  But even the tiniest heading change (or wind change) will slide you 90 degrees left or right.  The opposite happens when you are flying downwind.  Aircraft heading changes produce proportionally smaller ground track heading changes.

Wind adds some unique challenges to flying circle holds that are actual circles from a ground perspective.

Coupling

I also wanted to say some brief words about coupling between axis, because it can be a bigger issue in circle holds than might first be expected.  Imagine you are flying a perfect circle hold in zero wind.  You are at a 30 degree bank, at your target airspeed, and at your target radius.  Now imagine you are a bit outside of the target radius.  You need to bank a bit more to tighten your turning radius.  But this tighter bank could cause a loss of altitude (basic airplane physics).  If the aircraft responds to the lost altitude with increased elevator, this will tighten your turn even more because you are banked.  It is easy to over shoot and end up inside the circle, which means the flight controller will command the aircraft to fly less of a bank, increasing the circle radius, but that creates more lift, more climb, etc.  Roll, pitch, and throttle can combine in some very awkward ways during a circle hold and that, along with wind and all the other aspects of basic aerodynamics and physics can make flying an accurate and stable circle hold a bit more of a challenge than you might first expect.

External Scripting

Hah, if you are still reading all the way down here, you are really a UAV geek (or you are following good skimming rules of reading the first paragraph, the last paragraph, and looking at the pictures.)

One of the fun things about the avior autopilot is that all the sensor data, attitude estimations, control surface positions, navigation state, and just about every other interesting variable is published in a giant hierarchical tree of name/value pairs.  If you’ve poked inside the windows registery, it’s kind of the same basic idea, except all in memory and very fast to access or update.

The cool thing about this is that we can expose external interfaces to this giant data structure and completely command or monitor the autopilot externally.  This enables a developer to write a perl or python script to monitor and command the autopilot.  What sorts of things could such a script do?

  • Command the autopilot to do a circle hold, then smoothly adjust the center point of the circle hold to produce interesting patterns in the UAV flight track.  That’s what this whole article is about.
  • Fly specific flight test maneuvers repeatably and accurately.  Do you want to nail down the exact stall speed of your aircraft under different scenarios?  You could write a script to fly the aircraft into a stall, then recover, climb to safe altitude, repeat.  You could write scripts to put the aircraft into all kinds of different specific flight situations and carefully record the data.  What is the elevator trim and power settings for level flight @ 25 kts, 30 kts, 35 kts, 40 kts, etc.  How about at a 5 degree bank, 10 degree bank, etc.
  • Create higher level intelligence without having to write code inside the core autopilot.  The autopilot does everything for the aircraft, and it must be reliable and robust and never fail or do something dumb.  This comes through long hours of flight testing.  Now you want to go fiddle around under the hood and change something?  That is begging for trouble!  Why not leave the autopilot alone and write your new functions in an external script?  Maybe you could write a fancy engine-out auto-land script that knows the basic performance characteristics of your aircraft and can plot and command an optimal approach path to touch down from any position and altitude to any landing strip in any wind conditions.

I’m Thankful for my Senior Telemaster

This Thanksgiving day I’m thankful for many blessings: family, friends, neighbors, shelter, food, our siberian husky who lived 16 years, and many other things.  The weather was nice Thanksgiving morning so I was thankful to have an hour to run out to the field first thing to do some flying.

On Thursday, November 22 (Thanksgiving day) my Senior Telemaster past an interesting milestone: 12 cumulative hours of fully autonomous flight. This may not sound like a whole lot, but it represents 58 separate flights over the span of 3 years. In every flight it has performed beautifully and majestically and very scale like. It is not a fast aircraft, but it’s solid, forgiving, and controllable even at very slow airspeeds. It has a lot of room, a lot of carrying capacity, and it’s very tolerant of CG changes. I have flown it on calm days and I have flown it in up to 27 kt winds (31 mph) that were gusting to higher at times. With a set speed of 30 kts there have been times it has been blown backwards in flight! She has seen sun, clouds, fog, drizzle, and even rain. Winter, summer, spring, fall, hot days, cold days — she’s seen just about everything. Through all of this it has been a solid, reliable, patient, unfailing work horse — and she’s still going as strong as ever!

She has been a test bed for 4 major autopilot revisions:

  • An original gumstix :gumstix” processor + a Xbow MNAV sensor head.
  • A gumstix “verdex”+ a sparkfun 6DOFv4 IMU
  • A gumstix “verdex” + a VectorNav VN-100T temperature calibrated IMU
  • A gumstix “overo” + a 3D Robotics APM2.5 “sensor head”

I recall one close call where I made a code+hardware change and didn’t check it thoroughly enough.  Transitioning to autonomous flight resulted in an immediate full throttle dive towards the earth.  I switched to manual mode (almost not quickly enough) and was able to manually recover from the dive just in the nick of time.  That is the only time I’ve put any serious flex on the wings!

I recall one landing when the farmer’s corn was 8′ tall and completely surrounding our little patch of flying field.  I typically had to come over the edge of the corn with inches to spare in order to get it down and stopped before the end of our flying field.  On this day we had crazy gusting cross winds and as I cleared the corn the wind just fell out from under the telemaster.  It dropped from maybe 10′ of altitude and came to a complete stop no more than 5′ from the approach edge of the corn.  That has to be my all time shorted landing with any aircraft (only counting landings on the wheels.) 🙂

So thanks to my trusty work horse for many good years of service with hopefully many more to come!

Hacking the APM2 Part #5: Flight Testing

This is the payoff video showing the hybrid autopilot system in action in the Resolution 3 airframe. (By the way, this is HD video so watch it full screen if you can!)

I am skipping many details between integrating the hardware and flying, but just as a quick overview:

We first integrated the system into a Senior Telemaster.  After 4 trips to the field over the span of 2 days, numerous flights, and a bunch of work in the evenings, we felt like the system was coming together and working every bit as well as it was supposed to.  There are always more things we could do with the telemaster airframe, but now that we were fairly confident that the system was working end-to-end as designed, we dropped it into our Resolution 3 (blended body, composite flying wing airframe.)  The new hybrid autopilot system needed some gain adjustments versus the old prototype autopilot so we guessed at those based on what changes were needed with the Telemaster configuration.

We enjoyed a flawless bungee launch of the wing, climbed to altitude, flipped over to AP mode, and the aircraft flew off flawlessly and ran through it’s demo routine without a hitch.  The clouds were dramatic and we noticed a rain squall moving in, so we landed and packed up just as the rain set in.

Here are some high points of the new system:

  • 800Mhz ARM processor (with hardware floating point) running a 15 state kalman filter and all the autopilot and navigation code.
  • WGS-84 math used for heading and route following.
  • Accurate yaw estimation when the filter converges.
  • Accurate wind estimation
  • 100hz sensor sampling, 100hz filter updates, 100hz autopilot and navigation updates, 100hz actuator updates with up to 400hz PWM signal generation rate for digital servos.
  • APM2 sensors.
  • Tablet/smart phone/laptop ground station interface.

If you just like airplanes, here’s some nice footage of our Telemaster landing.  This video was taken during our 2 days of Telemaster integration effort …

Landing in psycho winds:

In calmer winds:

Last flight of the day:

Hacking the APM2 Part #4: Laying out a “hybrid” system

Imagine for one second that you are a UAV developer. The DIYdrones ArduPilot is an awesome piece of hardware; you love all the great sensors that are attached; you love the all-in-one design and the small/light size.  But you are also feeling the limits of it’s ATMega 2560 processor and the limits of it’s 256Kb of RAM.  And maybe, you enjoy developing code within a full blown Linux developers environment with all the supporting libraries and device drivers that Linux has to offer.

Hardware Layout

Here is a picture of a protype “hybrid” autopilot system for small UAV’s.  What you see in the picture includes:

  • An ArduPilot Mega 2.0 (lower left)  The APM2 includes an MPU-6000 IMU, a Mediatek 5hz GPS, static pressure sensor, compass, and a variety of other items.
  • A 1Ghz Gumstix Overo with a Pinto-TH expansion board. (longer thinner board, upper right).  The Overo runs Linux, has 512Mb of RAM, and has a hardware floating point processor.
  • An MPXV7002DP pressure sensor (upper left).  This is attached to a pitot tube and measures airspeed.
  • A Sparkfun TTL level translator (between the overo and the pressure sensor)
  • A Futaba FASST 6 channel receiver (lower right)
  • A set of power distribution rails (8×3 block of 0.1″ pins.)
  • [not shown/mounted remotely] Digi Xtend 900Mhz radio modem.

The above picture was deliberately taken without most of the wires to show the components.  Once all the wires are connected, things will look much more “busy”.  This is a prototype system so the components will be jumpered together, probably with a bit of hot glue here and there to ultimately secure the wiring before flight.

Software Layout

Just as important as the hardware layout is the software layout.  This is maybe a bit more boring and I can’t really take a picture of it to post here, but I will give a few bullet points for anyone who might be interested.

  • The APM2 runs a custom built firmware that simply collects all the sensor data, packages it up into checksummed binary packets, and sends the data out over a uart.  In addition, the APM2 reads checksummed binary packets inbound over the same uart.  Generally inbound packets are actuator commands.
  • The Overo runs a custom built autopilot application that is portable.  It is not device/hardware independent, but it is designed to talk to a variety of hardware over a common interfaces.  This Linux-based autopilot app can read all the sensor data from the APM2 (being transmitted at 100hz over a 500,000 baud link.)  The autopilot app runs a computationally intensive 15-state kalman filter.  Manages the mission tasks, computes wgs-84 great circle navigation targets, runs the low level PID code, and ultimately sends servo position commands back to the APM2 over the same 500,000 baud link.
  • The high level autopilot software runs in an environment that is more natural and has more power/space for developing the “high concept” portions of the code.  The APM2 is great for reading a bunch of sensors really quickly.  In a hybrid system both major components are able to do what they do best without having to suffer through tasks they aren’t as good at.
  • The high level autopilot is configurable through a structured XML configuration system.  It includes an advanced 15-state kalman filter.  It runs the same PID code configured in the same way as the FlightGear flight simulator.  It also includes the same “property system” that FlightGear pioneered.  It includes a rich set of IO API’s, and hopefully will soon sport a built in scripting engine.
  • A word about the “property system”:  The property system is an in-memory tree structure that relates “ascii” variable names to corresponding values.  There is loose type checking and on-the-fly type conversion similar to many scripting systems (I can write a value as a ‘string’ and read it back out as a ‘double’ and the system does sensible conversions for me.)  Any internal module can read/write the property tree, so it is a great way to build “loose” interfaces between modules.  Modules simply reference the values they need and there is no compile time enforcement.  This allows for building “robust” interfaces and eliminates much of the cascading changes throughout the code when a class gets updated.  In addition, we can build external network interfaces to the property system which allows external scripts or other code to monitor and even modify the property tree.  This allows external scripts access to the core values of the sim and access to set modes and otherwise “drive” what the autopilot does.  In addition, there is a natural one-to-one mapping between the property tree and an xml config file.  This is handy for easily loading/saving configurations.  At a low level, property system variable access from the core code is simply a pointer dereference, so using these values is almost as fast as referencing a locally scoped variable.  It is hard to describe in a few words what all the “property system” is or does, but it’s an amazing infrastructure tool that helps build flexible, robust, and high functioning code.

September 7, 2012 Update:

Here is a picture showing the whole system plugged together with 6″ sparkfun jumper wires.  The wiring gets a little “busy” when everything is connected together so I plan to do some work buttoning things up, simplifying, and cleaning up the wire runs.  I’ve attached 3 servos to test auto vs. manual outputs.  You can see a 900Mhz Xtend modem (1 watt power, 115,200 baud), and the entire system is powered by a single RC receiver battery.  In the aircraft this should all run just fine off the BEC.  And here is a video of everything in action:

That’s about it. The modified APM2 firmware is happy and running.  The overo autopilot code is up and running and talking to the APM2.  Next up is validating the radio modem ground station connection, and then I’m running out of things to do before dropping this into an airplane!

September 17, 2012 Update:

It’s far from a perfect integration, but I spent some time this evening bundling up wires.  Definitely an improvement.  Working towards full integration into a Senior Telemaster (electric powered) and hope to do some first test flights later this week.  Today I test fit everything, powered everything from the main flight battery and verified basic control surface movements in manual mode and autopilot mode.  The radio modem link is running and the mapping and instrument panel views on the ground link up and run.

Hacking the APM2 Part #3: Servos

Here are a few random notes on the APM2 and servos.

As we all know, the servos are controlled by sending a digital pulse on the signal line to the servo.  The length (time) of the pulse maps to the position of the servo.  A 1500us pulse is roughly the center point.  900us is roughly one extreme and 2100us is roughly the other extreme.  Different systems will use slightly different numbers and ranges, but these are good numbers to start with.  Historically, RC systems stacked the pulses for multiple channels on a single radio signal — affectionately called the “pulse train.”  If you crunch the numbers — given a max pulse width of about 2000us and a bit of inter-pulse spacing, we can send about 8-10 channels of data at 50hz on a single signal line.  Standard analog servos are designed to expect 50 pulses per second and can misbehave if we send a faster signal.

With modern 2.4Ghz systems, the servo/channel data is sent digitally and at much faster data rates.  Receivers drive each servo pulse concurrently and the concept of a “pulse train” is largely gone — as is the need to space things out at a 50hz rate.  If you crunch the numbers again and look at a max pulse width of 2000us with a bit of inter-pulse space, we can actually send servo data at 400hz to a digital servo and it will respond as expected.  (8 channels at 50hz, 1 channel at 400hz — makes sense.) 🙂

What does all this mean to an UAS builder?

  • It means that if we use digital servos, we can send position updates to the servo and expect some response at up to a 400hz rate. In real life these servos have mass, motors that take time to move, on board electronics that take time to process the signal, and other factors, so we can’t expect instantaneous response, but we can expect an improvement over the old 50hz analog servos.
  • It means we have a strong motivation to sample our sensors faster than 50hz, run our attitude filter faster than 50hz, run our guidance, control, and navigation code faster than 50hz, and command our actuators faster than 50hz.
  • It means that if we can increase our throughput to 100hz or 200hz, we can have a far more responsive and “tight” system than we could if everything was running at 50hz.  Faster response to gusts and disturbances, ability to counter more of the aircraft’s natural dynamics.  With proper autopilot tuning, this can lead to a much higher quality system, much more accurate flying, and a much more stable platform to hang our sensors off of.

The APM2 has the ability to set the PWM frequency for the output channels.  Channels are grouped and several hang from a single clock generator so we can’t change the PWM rate individually, but we can do it for groups of channels.  Question: if our system is running at a full 100hz update rate, does it make sense to set the servo output rate to 100hz or something higher?  I argue that we should set the output rate as high as is possible (400hz) because the servo will pick up a change fractionally quicker at a 400hz output rate than at a 100hz output rate.  In the end though, most servos are somewhat noisy and crude and subject to physics, so it may not have a huge noticeable effect, but any little thing that makes the system more responsive and increases the end to end throughput from sensing to responding is welcome.

Hacking the APM2 Part #2: Fun with Baud Rates

The autopilot architecture I am building involves and APM2 collecting all the sensor data and sending it over a serial connection to a Gumstix Overo running Linux, and then in return the Overo sends servo commands back to the APM2.  As you can guess, this turns out to be quite a bit of data being sent at a high rate.  If all the processing, filtering, and computation is being done on the Overo it is important to have a high update rate, low latency, reliable communication, and no major pauses in processing at either end.

In this architecture, the APM2 isn’t running the DCM filter.  It is not logging to the SD card, it is not communicating with the ground station.  It is simply collecting all the sensor data and blasting it across the data pipe to the Overo.

First let’s do a little math.  I have 6 packet types (so far) of varying sizes: Pilot Input = 16 bytes, IMU = 14 bytes, GPS = 36 bytes, Barometer = 12 bytes, Analog Inputs = 10 bytes, Actuator Commands = 16 bytes.  In addition, each binary packet has 2 start bytes, a packet ID, a size byte, and a 2-byte checksum — a six byte wrapper.  Assuming we send one of each packet, that would be 140 bytes.  Assuming we want to send a set of these packets 100 times a second, that is 14,000 bytes per second.  (I realize we don’t send the gps data at 100hz, but for the sake of simplicity and margins, let’s pretend we do.)  Now assume for the purposes of computing required baud rates, there are 10 bits per byte.  That means we would need to run at least at 140,000 baud to handle all the traffic we need.

Many software packages (including the arduino dev system and the arduino docs) seem to think that 115,200 baud is that maximum rate possible, so this could be a problem!

The next “standard” baud rate above 115,200 is 230,400.  It turns out that the APM2 FastSerial code happily let’s me specify this baud rate and my Linux based Overo does as well.  I tested this with the USB console connection and it works.  (Or so I thought.)

My next task was to get the communication link running on a direct UART connection.  This will simplify aircraft integration, reduce cable weight, etc.  However, as soon as I moved to a direct connection, the APM2 could no longer see data coming back from the Overo at 230,000 baud.  What is going on here?

The standard baud rates since the beginning of time have always been 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115,200, 230,400, etc.  However, when I dug into the Arduino FastSerial code and the Mega 2560 data sheet I discovered that the Arduino does things completely differently.  Baud rate is defined relative the system clock divided by an integer value.  When you ask for 115,200 baud, FastSerial crunches that value through a funny formula, comes up with an approximate integer divider and sets the baud based on that.  So when you crunch the math, what baud rates does the Arduino actually support?  It turns out you can do: 1,000,000, 500,000, 333,333, 250,000, 200,000, 166,666, 142,857, 125,000, 111,111, 100,000, 90,909, … etc.

So here’s the funny thing.  The uarts at both ends have some flexibility and can successfully communicate even if the other end isn’t exactly on the correct pace.  When you request 115,200 baud on the APM2, you are actually getting 111,111 baud!  But the other end can usually handle a little slop and no one ever notices.  The problem is that the arduino cannot do 230,400 baud — the options are either 200,000 or 250,000 baud and both of them are too far away from 230,400 to handle the timing slop.  In my case, the Overo actually could handle the APM2 output, but the APM2 couldn’t read the 230,400 baud incoming data from the Overo.

!@#$@#$!@!!!!

The next question I asked myself was how hard would it be to rewrite the linux serial drivers to support different baud rates, but quickly I decided that was just a path I didn’t want to head down unless there was absolutely no other option.

Finally I started looking to see if there were any matching (or very close) baud rate options faster than 115,200.  The only one I could find was 500,000 baud.  But that’s crazy fast and couldn’t possibly work, right?  Well if my other option is to start hacking linux serial drivers, I decided I could at least set the baud on both ends to 500,000 and see what happens.

And the answer is:  IT WORKED!

So I’m running 500,000 baud between the APM2 and the Gumstix Overo.

There are questions though — can the APM2 keep up with this?  Can the Overo keep up with this? What happens if the system is busy processing interrupts.  Are the ring buffers big enough to keep up?  Will we drop data?  Are there other hidden places where this could all break down or blow up?  I think the answers to those questions remain to be worked out and depend quite a bit on the loads at each end of the pipe.  This gets back to the delicate balance required by embedded systems and the requirement to carefully work your way forward and understand the systems at all levels in order to achieve a solid result.

Question: if 100hz updates require about 140,000 baud, then 200hz updates would require 280,000 baud — hmmm.  Does this mean it would be possible to sample the sensors at 200hz, send the data to the 1Ghz Overo at 200hz, run my kalman filter attitude estimate at 200hz, run my autopilot PID’s at 200hz, my navigation code at 200hz, and send actuator commands back at 200hz?  (Assuming digital servos that can respond to PWM rates as high as 400hz.)

Update: September 4, 2012

I have reconfirmed that the Gumstix Overo cannot transmit two serial streams simultaneously.  I use one serial port for the APM2 interface and one serial port for the wireless ground station interface.  The issue is that if I dump a big chunk of data @ 115,200 baud from the flight computer to the ground station, no APM2 communication can happen until that transaction flushes through.  The strategy I will employ for now is to stuff ground station messages into a local (user space) buffer and then trickle a few bytes out per frame to the serial driver.  This forces me to pace the ground station messages so I don’t overflow my application level buffer (which would reject new messages until there is sufficient space freed up) but that is something I need to do anyway because there is finite capacity in the bandwidth to my radio modem and the radio modem itself has finite capacity which diminishes with distance.  Just another reminder that with embedded systems we can’t have everything we want simultaneously, and the trick is to find a good (and delicate) balance between all the different components and needs.

Update September 7, 2012

Life is never easy!  I have discovered the Overo serial drivers in the Linux 3.x kernel now work a lot harder to match the standard baud rates very closely:  115,200, 230,400, 460,800, and 921,600.  None of these are a close enough match to the APM2’s list of nonstandard baud rates — 200,000, 250,000, 333,333, 500,000, and 1,000,000.  This is a major annoyance!!!  The Overo serial drivers in the Linux 2.6.x kernels seemed to do an actual 500,000 baud, but unfortunately that is gone.  It all has to do with clock dividers and stuff.

What I have done for the moment is work on trimming some of the fat off my binary packets and I’m sending data at 115,200 baud which does (thankfully) still work!  This is sufficient for my current needs so I can move forward, but it does quell any thoughts of running everything end-to-end at 200hz on this layout.  But perhaps with some attention to trimming more fat and perhaps only sending core IMU data at 200hz we could still build a system that inherently has 200hz throughput where it matters.

Hacking the APM2 Part #1: Introduction

Introduction

I would like to start off my first post in this series by briefly describing where I’ve been and where I’m going.  Hopefully this will give a bit of context to help understand subsequent posts and hopefully will help put my engineering decisions in some context.

History of the World, Part 1

Somewhere around 2005 I became very interested in aerial robotics.  I have always been an aviation enthusiast, I’ve built model airplanes since I was a kid, and I have been flying RC airplanes since high school.  At the time I was working for the Univ. of Minnesota and managed to get myself sent off to a training class for a little device called a Crossbow MNAV.  The MNAV was a small package that included mems gyros, accelerometers, altimeter, air speed, GPS, RC receiver PPM train decoding, and could control up to 8 servos.  It was perfect for building a small UAV autopilot.  As it turned out, even though the MNAV was pretty good for it’s time, it wasn’t perfect — and about 2 years later when I finally had my code up and flying successfully, Xbow announced they had discontinued the MNAV.

My autopilot code was written for Linux.  I had been running it on a 400mhz Gumstix processor (the really old one) and that talked to the MNAV over a serial connection.  The MNAV sent up the IMU and GPS data to the Gumstix which ran the attitude filter, autopilot, and navigation code, and sent servo positions back to the MNAV.  This worked rather well so I was pretty disappointed when the MNAV was terminated.

History of the World, Part 2

In a world with no MNAV I launched off on an adventure to build my own autopilot from off the shelf parts.  What made this possible was the original ArduPilot.  I could buy IMUs, GPSs, and processors off the shelf, but the ArduPilot gave me the ability to interact with RC servos, the RC receiver, and gave me a hardware failsafe mux, so whenever something went wrong with my code, I could immediately take over manual control of the aircraft.  As it turns out, this has saved me more times than I can count.

I ended up with a system built around the new Gumstix Verdex “pro”.  This processor ran at a whopping 600mhz and had enough number crunching power to run a full blown 15-state kalman filter at 50hz.  I connected a SparkFun 6DOFv4 IMU initially (ultimately upgraded to a VectorNav VN-100) for my inertial sensor, a ublox5 for my GPS, and of course the original ArduPilot for servo control.

At that time I hacked my own version of the ArduPilot firmware to talk directly to the Gumstix Verdex.  I left out all the AP stuff and simply used it to read the RC receiver and relay the pilot stick commands to the Gumstix, and then the Gumstix would send back servo positions to the ArduPilot which would take care of moving the servos to the specified positions.

History of the World Part 3

Time passes, a few projects came and went.  Now it’s 2012, and now the APM2 is released.  Compared to the original ArduPilot, the APM2 is a beautiful work of art!  It looks good, it packs on all kinds of high quality sensors, it has a powerful at mega 2560 processor, it is small, it is light, it is cheap, and it’s pretty well debugged because so many people are buying and flying them.

I decided it would be interesting to revisit my old autopilot design and modernize it based on the new APM2.  Any set of engineering decisions has plusses and minues.  Embedded autopilots are always a delicate balance between, size, weight, cost, capability, power requirements, etc.  And within those larger parameters, every architectural choice has subtle implications related to performance, latency, precision, capability, development tools, integration issues, unexpected surprises (good and bad), and on and on. On the one hand, there is a huge matrix of possibilities, and on the other hand specific choices have cascading effects and lead you in specific directions.  In the end, the goal is to find that magic balance of choices that lead you to an ideal outcome without sacrificing too many things along the way.

Looking to the Future

Where am I going with all this?  What do I envision my autopilot will look like at the end of the process?  Here is a quick summary:

  • An APM2 with firmware rewritten to simply collect all the sensor data and pass it up stream to my Gumstix for actual processing.
  • A Gumstix Verdex (1Ghz Arm) with hardware floating point, 512Mb of RAM
  • Linux based Autopilot software that includes a full 15-state kalman filter, XML configurable PID system, and advanced mission/task system.
  • Everything running at 200hz.
My work on this project has begun.  There are many challenges and unknowns that have already been met and solved, and I’m sure a few remaining challenges hiding on the other side of the horizon.  This just scratching the surface — I have been flying autonomous RC planes since 2007 with a variety of sensors and processors.  The autopilot itself is certainly a goal for me, but it is also a doorway we have to pass through to be able to work on so much more.

I plan to continue this “Hacking the APM2” series with future posts describing interesting things that I’ve learned or issues that I’ve solved along the path; culminating (hopefully) with a “Super ArduPilot Mega 2 on 1Ghz ARM Steroids” based autopilot system.

Resolution 3: Design Evolution to First Flight

Here is a photo blog showing the progress from initial rough prototype, to final design, to mold making, to test flying the first production aircraft:

Resolution 3: Design to First Flight

This is a project that was sponsored by NOAA to develop a fully marinized small UAS that could be deployed from a variety of small vessels, recovered in the water, and used for marine debris detection or wild life surveys.

The “Resolution 3” purpose built UAS airframe is just one of the really cool products to evolve out of this project.

Visualizing Circle Holds

(If it was me, I’d click on the “watch on youtube” icon in the lower right corner and select 480p and go full screen — but that’s just me.)

Flying a continuous tight circle pattern around a fixed ground reference point is about the closest thing we can get to parking an airplane in flight. It isn’t too hard to do a lazy orbit around the point, but we want to keep the radius fixed, even if there is a wind. This means that as we fly around the perimeter of the circle we have to continually vary our bank angle and turn at different rates relative to the wind so that our ground track maintains a perfect circle of the desired radius.

Here are some things to look for in the movie:

  • I’ve turned up the turbulence to moderate levels so the small aircraft gets bounced around quite a bit.  Still in the last shot you can see that the flight controller has maintained a pretty tight circle the whole time.
  • This is a 3d model of the new ATI Resolution 3 (a small marinized UAS.)  Stay tuned for more details if you are interested in that sort of thing.
  • FlightGear offers a variety of interesting view points and visualization tools, including smoke and trajectory markers, HUD overlay, animated control surfaces, realistic environments, wind and turbulence.
  • If you look carefully, you can see how the smoke drifts relative to the red/blue trajectory markers.
  • This is all part of a demo package I am putting together that shows things like autonomous-takeoff and landings, a gyro stabilized camera simulation, circle holds around a point, route following, a cool new UAS airframe under development — all mixed in with FlightGear’s wonderful prototyping and visualization features.

Real-time UAS Simulation and Visualization

Real-time UAS Simulation and Visualization

In previous posts I’ve described the process of carefully modelling the basic geometry and mass properties of a UAS in YASim to provide a real time flight dynamics simulation of the aircraft in FlightGear.  I also described how we carefully modelled the blended body shape of our UAS using airfoil plots and spline curves.  These curves were then imported into MoI and used as the basis to generate a smooth, flowing, organic surface shape.  MoI is able to export the model as a 3d triangle mesh in a variety of formats including 3ds.

Model Cleanup

FlightGear can directly import 3ds models and render them in the simulator.  However, I found that my model needed be cleaned up in several respects.  All of this discussion relates to Blender – a very capable open-source 3d modeling tool. This isn’t intended to be a blender tutorial, but a brief overview of the steps involved in preparing a model for use within FlightGear

  1. Surface smoothing: If you click on the above thumbnail you will see that the basic model imported from MoI is “faceted” or in other words, the triangle surfaces are flat and you don’t see the intended smooth curved surface.  One of the first steps required is to select each “Object” and select “Set Smooth” in the “Buttons Window”.  Repeat for each object in the model.
  2. Inside-out surfaces: I decided for simplicity, I would export the model in the .ac3d format (a text based format) for final use in FlightGear.  When I did the export I discovered many of the surfaces where inside out — the face normals were pointing in rather than out.  This causes the surface to be displayed inside out and shaded wrong in FlightGear.  So the next step required is to turn on the display of face normals, select each object individual (right mouse click), enter “Edit Mode” <tab> key, and flip the face normals if needed.
  3. Orientation: FlightGear allows you to add an xml wrapper around your model to adjust the orientation of your model (flip it by 90 degrees for example) in case the model was developed for a different coordinate frame layout.  However, since I was doing all the prep work anyway, I rotated the heading of my model by 90 degrees in blender so I didn’t need any extra transforms when drawing the model inside FlightGear.
  4. Scaling: For convenience and due to the scale of this design, all the original work was done in inches.  This transfered to the MoI model and thus to the blender and flightgear models as well.  However, FlightGear requires units of meters so the model was grossly oversized when imported into the simulator.  Blender has a scale function, so I selected the entire model and scaled it by a factor of 0.0254 to convert from inches to meters.
  5. Control Surfaces: this aircraft is a flying wing and has as very simple control system.  Each wing has a strip elevon that runs the length of the wing.  Aileron and elevator inputs are mixed (summed) to produce the actual control surface deflection.  In the real UAV, this mixing is accomplished in the flight control software.  On an RC airplane this mixing would be done inside the pilot’s transmitter on the ground.  In FlightGear, the mixing is done through the YAsim xml config file.  Blender has a cut function accessed by typing “Shift-K”.  I went into top view mode, drew lines for the control surface cuts and cut the mesh to create the elevons.

Textures and Painting and UV Unwrapping

This could be the subject of a book just by itself, but let me give a really quick summary.

Blender has a cool feature called “UV Unwrap” which is found in the “Mesh” menu when you are in “Edit Mode”.  There are several unwrap options, but I found “Unwrap (Smart mode)” worked the best for my purposes.  The following image shows how blender unwraps the mesh (in this case the wings and elevons.)  In the bottom panel I selected “UV/Image Editor” and it shows the unwrapped mesh image.

Now here’s the cool thing.  You can save this image out to a file and then import it back in.  Blender will use the imported image to texture the file exactly as it has been unwrapped.  So with this template image you would see a model that looks like a wireframe.  I then loaded up the images in blender and labeled each panel with a big number.  Inside FlightGear (or osgviewer) I could then identify which number corresponded to which panel (top left, bottom right, etc.)  I further edited the template file to include this extra information.  The result when drawn in FlightGear looks like this:

Now I have my “paint kit”.  I can load up the templates in gimp (or photoshop), create a new layer, and draw my color schemes and markings over the top.  For the wing panels, I did a quick hack of a coast guard-ish color scheme which looks like this:

I then export just the marking/paint layer back out to my texture files that the model references and the “finished” result looks like this:

This is still a work in progress.  I have yet to animate the control surfaces.  I also need to add a spinning propeller.  The paint scheme is just a quick example and could use many many improvements.

With the paint kit established, a variety of paint schemes can be developed.  Here are two more examples:

Official ATI scheme:

A gray camouflage scheme:

Summary

There are many steps required to model a new aircraft design in FlightGear.  Primarily this involves creating a flight dynamics (physics) model and a 3d model of the design.  Each step requires several sub-steps and there is always room for improvements and refinements.  This is an example of an R/C scale UAV.  Full scale aircraft are much more complicated involve detailed cockpits, many more animations, much more complicated 3d meshes, and much more work texturing and painting.  Hopefully I have provided a taste of what’s involved.  With a little effort any one can jump in and learn the tools to build simulated aircraft.  But it does take time and patience.

Finally, here is a (sorry, kind of crude) youtube video showing the model flying inside FlightGear: