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.

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.

Better FlightGear Smoke

Overview

A popular way to create smoke effects in visual simulation is through particle systems.  Briefly, a particle system emits particles.  Each particle can have a texture as well as a variety of physical characteristics.  Particles can be shot or just placed in the world.  If you shoot your particles you can control a randomize range of angles and speeds.  You can give your particles a life span in seconds and have them grow or shrink over their life.  Particles can have mass and surface area which affects their motion.  They can move relative to the world or relative to the shooter.  They can blow in the wind, they can spin in various axis; there are many cool things you can do with particles!

I am going to focus on a smoke trail emitted by an aircraft engine.  Often, aerobatic aircraft are rigged to dump  a special oil into the hot engine exhaust which creates a thick smoke trail.  This is really cool at air shows.

We would like to simulate this effect in FlightGear and we do.  However, I’m a little unsatisfied with some of the existing particle configurations.  I’ve seen much better in other packages.  I have carefully made some improvements which I will explain here.  Hopefully other aircraft developers can take this and run with it and make their smoke effects look even better.

Example

For detailed documentation on the FlightGear particle system, please consult the file README.xmlparticles in the FlightGear documentation folder (included with every installation.) Here is an example xml config file I have been working with to create smoke effects for my small UAV models:

  <particlesystem>
    <name>smoke</name>
 
    <offsets>
      <x-m>  0.000 </x-m>
      <y-m>  0.000 </y-m>
      <z-m>  0.000 </z-m>
      <roll-deg>    0.000 </roll-deg>
      <pitch-deg>   0.000 </pitch-deg>
      <heading-deg> 0.000 </heading-deg>
    </offsets>
 
    <texture>smoke.png</texture>
 
    <condition>
      <property>sim/multiplay/generic/int[0]</property>
    </condition>
 
    <emissive>false</emissive>
    <lighting>false</lighting>
    <align>billboard</align> <!-- billboard / fixed -->
    <attach>world</attach> <!-- world / local-->
 
    <placer>
      <type>point</type> <!-- sector / segments / point -->
    </placer>
 
    <shooter>
      <theta-min-deg>70</theta-min-deg>
      <theta-max-deg>110</theta-max-deg>
      <phi-min-deg>70</phi-min-deg>
      <phi-max-deg>110</phi-max-deg>
      <speed-mps>
        <value>10</value>
        <spread>5</spread>
      </speed-mps>
      <rotation-speed>
        <x-min-deg-sec>0</x-min-deg-sec>
        <y-min-deg-sec>0</y-min-deg-sec>
        <z-min-deg-sec>-180</z-min-deg-sec>
        <x-max-deg-sec>0</x-max-deg-sec>
        <y-max-deg-sec>0</y-max-deg-sec>
        <z-max-deg-sec>180</z-max-deg-sec>
      </rotation-speed>
    </shooter>
 
    <counter>
      <particles-per-sec>
        <value>200</value>
        <spread>5</spread>
      </particles-per-sec>
    </counter>
 
    <particle>
      <start>
        <color>
          <red><value>   1.0 </value></red>
          <green><value> 1.0 </value></green>
          <blue><value>  1.0 </value></blue>
          <alpha><value> 0.3 </value></alpha>
        </color>
        <size>
          <value>0.2</value>
        </size>
      </start>
 
      <end>
        <color>
          <red><value>   0.95  </value></red>
          <green><value> 0.95  </value></green>
          <blue><value>  0.95  </value></blue>
          <alpha><value> 0.001 </value></alpha>
        </color>
        <size>
          <value>5.0</value>
        </size>
      </end>
 
      <life-sec>
        <value>30</value>
      </life-sec>
 
      <mass-kg>0.1</mass-kg>
      <radius-m>0.25</radius-m>
    </particle>
 
    <program>
      <fluid>air</fluid>         <!-- air / water -->
      <gravity>false</gravity>
      <wind>true</wind>
    </program>
 
  </particlesystem>

Again, rather than explain everything in detail, I just want to touch on several items that perhaps are being misunderstood or overlooked.

  • Shooter theta and phi: These values control the range of angle that particles are shot from the emitter.  It is important to notice that these angles are specified in degrees.  A theta value of 0 degrees is straight up and a phi value of the 0 degrees is out the right hand wing.  So if you want your particles to be emitted straight out the back, you want both phi and theta to be 90 degrees.  However the smoke gets mixed up in the wake turbulence coming off the aircraft so the puffs go in different directions.  In this example I’ve set a max/min range for both theta and phi of 70 to 110 degrees.  This is +/- 20 degrees from straight out the back.
    Update: May 12, 2011: The phi/theta values actually depend on your overall model orientation. I recommend you setup a positive shooter speed, zero wind, and then play with these numbers when the model is sitting on the ground to make sure you have the angles and orientations correct.
  • Shooter speed: Smoke quickly mixes with the atmosphere and blows with the prevailing wind, so shooting the smoke at a particular speed is not too important.  However, in terms of creating some randomization to the smoke trail it does help to shoot the initial puffs in a variety of directions and speeds.
  • Rotation speed: This is a very important one that I’ve seen misused in several configurations.  Notice that particles are billboarded so they always face the viewer.  If you look at a “sprite” edge on, you see it’s flatness and that doesn’t look right.  We do want some rotation though, this gives the effect of the swirling vortexes coming off the wing tips and tail of an aircraft.  As the smoke gets mixed up in the air currents, you can visually see it spin in real life.  Here is the critical thing to notice: if you give any rotation in x and y, you will be tumbling the surface that the particle image is drawn on and the viewer will see the edge on sprite and it won’t look right.  However if you rotate in the z axis, you get what you want, a sprite that always faces the viewer but spins either clockwise or counter clockwise depending on the spin rate you specify.  In this example I use +/- 180 deg/sec which seems to work pretty well.
  • Counter particles-per-sec: Another thing I played with was how many particles per second are emitted.  You need to to balance the particle size with the number emitted against your computer graphics speed to try to come up with a realistic smoke trail.  Ideally you would use lots of smaller particles, but this can affect render speeds.  So you might want to increase the size of the particles and then generate them at a slower rate.  You can also control the lifespan of your particles so shortening that up is another way to reduce graphics load.
  • Particle start and end size: You can can specify a starting size of the particle and an ending size of the particle.  You also specify the life-span of the particle, so it will grow linearly to the ending size over the course of it’s life.  This is important with smoke effects because if you focus on a single point in a smoke trail, you will see the smoke expand and then dissipate.  We can simulate this by making our particles grow over time.
  • Particle physics: You can specify the mass of each particle as well as it’s radius.  These numbers do not affect the size as it’s drawn on screen, but do affect the motion of the particles.  If you create a very light particle (0.001kg) with a large radius (1m) then it doesn’t matter what direction or how fast you shoot the particle, it will immediately follow the local airmass.  The problem with this is that you get a very uniform smoke trail with no variation at all.  If you increase the mass (1kg) and decrease the radius (0.1m) suddenly your smoke particles start acting like rubber balls and they shoot out in a scatter pattern.  So the trick is to find the right balance of mass and radius so that your particles scatter a bit to simulate turbulent air behind the aircraft, but not too much and not too little.  The numbers I came up with were mass = 0.1kg and radius=0.25m.
  • Texture: One other important thing to mention is the texture.  You have control over the texture that gets drawn for each puff (particle) of smoke.  There are example textures you can copy from other aircraft or you could make your own.  Generally I like smoke/cloud textures that are all white, and vary only in transparency.  However, for smoke particles, giving a little shading on your particle bitmap might look nice and give a bit more variation to the smoke trail.  Also it will help show off the spinning vortexes a bit better.  As you can see in my screenshots, the current smoke texture is probably a bit too dark in places — yet another thing to try to balance into the overall effect.

I think I have taken several significant strides forward to create a better smoke trail configuration for FlightGear, however, I’ve still seen better in other software packages.  This is something I will continue to work on and hopefully other developers will pick up on too, now that they know exactly what parameters they need to tune and why.

UAS Visualation

Smoke trails and trajectory markers can be two great tools when prototyping and developing UAS flight control systems.  Trajectory markers show the absolute flight path in world coordinates, and a smoke trail shows the relative path in the air mass.  Turn them both on at the same time to see how they relate to each other.  This enables an engineer to see exactly what their aircraft is doing under a variety of wind and turbulence conditions.