-
Doing the math
03/05/2019 at 09:20 • 0 commentsFrom the original list of features I sketched out a year or two ago, I primarily want address the following:
As a pilot I want to know how much fuel is onboard, expressed as time.
As a pilot I want to be alerted when I am approaching my reserve fuel time.
As a pilot I want to know when the active fuel tank needs to be changed so I can keep the tanks balanced.
As a pilot I want to know when my search and rescue deadline (SARTIME) is approaching so I can update or terminate it.
As a pilot I want this device to keep state accurately across loss of power or reset so I do not lose information.
Common to all of these are two calculations:
- Difference between two date/times
- Time remaining given a quantity and rate of consumption
These calculations have to be reliable, but not necessarily fast. As long as the system stays responsive on a human scale (eg. a few hundred milliseconds when a button is pushed). This makes the main constraints program size and memory.
Half of the ATMega328p's 2KB of SRAM is currently taken up by a screen buffer, but that could be reduced at the cost of draw time if needed.
Diffing date/times on an AVR
Time is fairly straight forward to store and read back. The real-time clock source for this project is a Maxim DS3231, which provides a date and time in binary coded decimal (BCD) format. This can be simply be stored as a series of 8-bit integers to avoid dealing with BCD values outside of the RTC read/write routines:
typedef struct RtcTime { uint8_t hour; uint8_t minute; uint8_t second; uint8_t day; uint8_t month; uint8_t year; } RtcTime;
It's easy to display this information, but as soon as you want to do any calculations the firmware needs to know all about how calendars work: days in months, months in year, and how leap years work. Reducing the problem to diffing times within the same day isn't suitable here as the clock needs to be set to UTC to compare against a configured SAR time. Where I live is 12-13 hours ahead of UTC, so it's very common for a flight to cross the boundary of a UTC day.
AVR libc provides a version of time.h with some modifications to make it more suitable for AVR microcontrollers, like using 32-bit integers instead of double-precision floats, but it still uses a fairly large chunk of program space just to diff two times. Calling only
mktime
anddifftime
increases the program size by around 1,500 bytes: 4.5% of the total program space on the 328p! Eachtm
struct also wastes 6 bytes of SRAM with fields that won't be used here.This project doesn't need completely general date/time functions (currently), so a more specialised time diff implementation can save a bit of space:
The DS3231 uses a two-digit year. Limiting the year to 2000-2099 simplifies leap year checks to bitwise operations.
Timezones and daylight saving offsets can be ignored as we're always comparing two UTC date/times.
The difference between times can be returned in minutes instead of seconds. A range of -22 to +22 days can be represented as minutes using a 16-bit value, which is more than enough here.
An implementation with these assumptions uses only 334 bytes of program space. With another small function, the seconds columns of two
RtcTime
structs could be diffed to supplement the delta of minutes with a remainder of seconds.How much fuel is left?
Fuel is a different beast to keep track of. The burn rate in flight (litres per hour) and capacity of each tank (litres) both fit comfortably into the 0-255 range for light aircraft, but to find the quantity remaining after an elapsed time requires much greater resolution than this. Enter fixed point math.
The resolution a fixed point number can represent is simply 1 over the scaling factor, so finding an appropriate scaling factor is fairly easy. For reference, a burn rate of 38L/h is exactly 10mL per second, or 600mL per minute.
Scaling factor Required type Resolution (approx) 28 Unsigned 16-bit 3.9mL 216 Unsigned 24-bit 0.15mL 224 Unsigned 32-bit 0.00006mL Scaling by 216 would be the minimum suitable resolution in this case to avoid accumulating too much error, but as 24-bit values aren't typically used (though they're technically supported by GCC), it's easier to use a 32-bit value and go with a 224 scaling factor. The result is a "UQ8.24" fixed-point value - enough resolution to only be millilitres out after days of operation.
Once we have a fixed point representation for the fuel quantity in each tank, we'll need a strategy to keep track of how much fuel is onboard. Let's explore a few:
Reduce the selected tank's quantity by the per-second burn rate for every second that passes.
I was considering using this for a while, and it would technically work, but it has some problems:
- Accumulates rounding error when splitting consumption between tanks (how much depends on chosen fixed-point precision and how evenly the burn rate divides by that)
- Requires a "catch-up" function to account for the time elapsed since the last persisted state after loss of power or reset.
- Potentially requires persisting state frequently to help reduce the catch-up required.
Store the start and stop time of each state of flight. Calculate remaining fuel as total fuel minus the burn in each recorded period.
This solves the issues from the previous idea:
- + Little accumulation of rounding error
- + Only need to persist data when state changes
- + No need for a "catch-up" routine as the calculation always reflects the given time.
However, it introduces one major issue:
- - Requires an unbounded amount of persistent storage
How about a small modification to keep storage bounded:
Store the start time of the current state of flight. When the state of flight changes, calculate the fuel used during the last state and subtract it from the current tank
- + Little accumulation of rounding error
- + Only need to persist data when state changes
- + No need for a "catch-up" routine
- + Requires a fixed amount of storage
This is the approach I'm planning to implement.
-
One year of tinkering update
12/04/2018 at 11:32 • 3 commentsThis project has existed in breadboard-form on my desk for 18 months. Though this is the first update in a while, it's a project I tinker on a lot: there's a menu system that's easy to work with, views can be pushed and popped, user input is transferred around automatically, and the event-loop is an interesting way to organise an embedded project. Problem is, none of these are core features. These things are polished not because they need to be, but because I've been putting off the harder task of making decisions about the in-flight views of the device.
Earlier in the project I'd sketched out a bunch of screens to see what might fit into in the limited screen resolution:
I wasn't too happy with the in-flight ideas (top row), particularly the "xfeed" ones where independent fuel tank timing isn't relevant and only a total value needs to be shown. The first few ideas all try to fit too much information on screen. Sure it all technically fits, but on a real screen, 3 small variations on the same number all cramped together in a small font aren't very easy to parse at a glance.
Menus on the other hand were dead simple (middle row above), and this is where I've put a lot of my tinkering time. There are a ton of examples of simple menu systems in existing products which are tried and tested - take any of Nokia's pre-Microsoft cellphones for example:
Recently I've gone back to pen and paper to design an in-flight view based on what information needs to be displayed, rather than how much I text can technically fit onto the display at once. The main piece of information is time remaining (this is just a souped-up countdown timer after all), so working with that I did some doodling:
Which turned into this mock-up at 128x64 (scaled up 10x here):
What also needs work is the hardware interface design, which up to this point has been a single rotary encoder. With recent time in the cockpit I've realised that the hardware interface for this project is pretty important.
In software land where I come from, it's pretty safe to assume that the user is looking at the screen, has the head-space to read messages, navigate the interface, and so on. In a cockpit environment, these assumptions are not going to be true most of the time. The interactions I expect to have with the device are during busy periods and need to be as predictable as possible: actions like starting and stopping the main timer essentially need to be done by feel with dedicated buttons rather than visually through the display.
I'm still working out what the hardware interface looks like, so more on that in a future post. I've been flying long routes as I work towards a commercial pilots licence, so I'm really looking forward to having this device in the cockpit soon.
-
Fuel management in light aircraft: why use time?
02/17/2017 at 18:50 • 1 commentIs this really state of the art, measuring used fuel just by time? Are there no fuel level sensors available just like in any car, or at least flow meters which measure fuel usage?
If my life depends on not running out of fuel it seems quite disturbing to just rely on absolutely constant fuel usage over time during the flight.— martin
Great questions. Using time is definitely not state of the art technology, and you're quite right that running out of fuel in an aircraft means you're gonna have a bad time.
From my flight training, experience and some research, I would say that the use of time comes down to operational aspects more than a lack of technology. Specifically, managing the phase of flight where accurate fuel information is the most critical: pre-flight planning.
When is fuel information relevant?
The amount of fuel onboard is arguably most relevant when you can add more - before you ever start the engine. Before you get into an aircraft, you want to know you have enough fuel for your intended trip, plus further flight to alternative/backup destinations, plus any legally required reserves (30 minutes for visual flight during the day in New Zealand). It's nice to confirm enroute with technology that everything is going to plan, but you'd never take off in an aircraft without redundant checks ensuring you have enough fuel for the time you want to fly. That said, searching the NTSB aviation database for "fuel exhaustion" returns 2,718 results for the period 1970 - 2017; one per week on average.
Part of the pre-flight inspection for most light aircraft includes 'dipping' the tanks with a calibrated stick to check the volume of fuel in the each tank. Larger aircraft use electronic gauges to check fuel quantity or weight during pre-flight, but even airliners still have physical dipstick devices for redundancy. Personally I don't check the fuel gauges in the cockpit until I'm in the process of starting the engine.
Calculating fuel time
"Half a tank" or any specific volume of fuel won't get you a reliable distance in an aircraft like it does in a car, so you can't just jump in and go. The amount of time required to travel a planned route is calculated by determining the ground speed for each portion of the trip based on intended cruise speed, altitude and forecast wind velocities
While it is possible to go into detail calculating different burn rates in different phases of the flight based on engine RPM and time spent climbing, having more fuel is almost always better. Hence, in practice it's easier and safer to base fuel requirement calculations on a constant high or maximum burn rate (especially for training operations), rather than trying to squeeze a little more load on board in place of fuel. If you're flying long distances at high altitudes you'd factor that in, but for a weekend warrior doing short trips, taking extra fuel isn't a problem.
If you ever got into a situation where you were running out of fuel time that was calculated using a high or maximum burn rate, you'd be unlikely to be complaining about the extra litres you might have available to get the plane down safely.
Fuel level sensors
To answer your second question, light aircraft do have car-like fuel level sensors in each tank, but they're generally not accurate enough to rely on as more than a cross-check against other calculations while in flight. Fuel level sensors rely on the aircraft being level and in balance (not yawing relative to the flight path, which can push fuel to either end of the tanks). Since an aircraft can rotate in space, these aren't always going to display correctly.
Digital/"glass" cockpits (like the Garmin G1000) tend to have numeric display of fuel quantity, which is more accurate to read than analogue gauges, but should still only be used as one of many sources of information - not used as the sole indicator like you do in a car.
Fuel management isn't so much about accurate gauges as it is planning though. The most accurate and readable fuel gauge in the world isn't any better than a crusty analogue one if it's telling you you're running out of fuel. The Pilot's Operating Handbook for a Cessna 182 with glass cockpit published in 2004 echoes this in its section on fuel systems:
it is important to utilize all available information to estimate the fuel required for the particular flight and to flight plan in a conservative manner.
As does other training material:
...in any event, gauge indications of fuel quantity should always be cross-checked - on the ground by visual inspection, which may require 'dipping' the tanks - and in the air by comparison with indicated fuel flow (if available), flight plan expectations, or previous experience of proven fuel usage under similar flight conditions.
— General Aircraft Technical Knowledge, tenth edition (2007, ISBN 0-9583373-7-3)
We have the technology
The technology to provide accurate fuel consumption information already exists in light aircraft with fully digital panels ("glass cockpits"). The Garmin G1000 for example can provide a calculated value of fuel consumption alongside numeric tank quantity gauges [ref page 91]:
Calculated Fuel Used (GAL USED)
Displays quantity of fuel used in gallons (gal) based on fuel flow since last resetBased on the mid 90's introduction of the Garmin G1000, it's a reasonably safe guesstimate that most light aircraft manufactured since the mid 2000's have come factory with glass cockpits with these features (I can't find exact figures on this though).
A lot of aircraft are old however - as in circa 1975. This is partly due to a huge downturn in light aircraft manufacturing in the USA in the 1980s and 1990s (due to accident liability concerns), and partly because older aircraft are considerably cheaper to purchase than their factory-new counterparts. Consequently, I've never flown an aircraft with a full glass panel in the four years I've been flying.
There's plenty of places to improve availability and accuracy of information in older cockpits with analogue instruments, and likely improvements to make in fully digital cockpits. Unfortunately this is not the kind of hobby where the CAA or FAA is ok for me to whack an Arduino and a digital flow meter on the fuel line; every piece of equipment has to be certified, and all work done by certified aircraft technicians.
This project will have to suffice until I can find a glass cockpit aircraft to fly. In any case even with the latest technology, I'll still be using a pen, paper and wrist watch as well.