Added barometeric altitude model and testcase

master
Richard Meadows 2015-08-02 14:03:49 +01:00
rodzic 9fb5d6cb20
commit 7f58ddee7b
5 zmienionych plików z 273 dodań i 0 usunięć

Wyświetl plik

@ -0,0 +1,30 @@
/*
* Calcuates altitude in a International Standard Atmosphere
* Copyright (C) 2013 richard
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ALTITUDE_H
#define ALTITUDE_H
double pressure_to_altitude(double pr);
#endif /* ALTITUDE_H */

Wyświetl plik

@ -0,0 +1,156 @@
/*
* Calcuates altitude in a International Standard Atmosphere
* Copyright (C) 2013 richard
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <math.h>
#include "samd20.h"
/**
* Useful Resources:
* Wikipedia: http://en.wikipedia.org/wiki/International_Standard_Atmosphere
* Wikipedia: http://en.wikipedia.org/wiki/Barometric_formula
*
* Online Calculator: http://www.digitaldutch.com/atmoscalc/
* (For Geopotential altitude, not Geometric)
*
* Mathematical Description: http://www.atmosculator.com/The%20Standard%20Atmosphere.html
*
* Test Data: http://www.wolframalpha.com/input/?i=air+pressure+at+11km+in+pascals
* (Works with Geometric altitude as you would expect, very clever)
*/
/* Layer Heights h0 -> h7 (km) */
double h[] = { 0, 11, 20, 32, 47, 51, 71, 84.8520 };
/* Base Pressures p0 -> p7 (Pa) */
double p[] = { 101325, 22632.0, 5474.89, 868.019,
110.906, 66.9388, 3.95642, 0.373384 };
/* Lapse Rate l0 -> l7 (K/km) */
double l[] = { -6.5, 0, 1.0, 2.8, 0, -2.8, -2, 0 };
/* Base Temperatures t0 -> t7 (K) */
double t[] = { 288.15, 216.65, 216.65, 228.65,
270.65, 270.65, 214.65, 186.946 };
/* Gas Constant of Air (J/kgK) */
#define R 287.053
/* Gravity at 45° Latitude (m/s2) */
#define G -9.80665
/* Volumetric Mean Radius of the Earth (km) */
#define RE 6371
/* Scaling Function: Height (m) */
double hi(int i) { return h[i] * 1000; }
/* Scaling Function: Lapse Rate (K/m) */
double lr(int i) { return l[i] / 1000; }
/**
* Returns the altitude within normal layer i at pressure pr.
*/
double normal_layer(double pr, int i) {
return hi(i) + (t[i] / lr(i)) * (pow(pr / p[i], (lr(i) * R) / G) - 1);
}
/**
* Returns the altitude within isothermic layer i at pressure pr.
*/
double isothermic_layer(double pr, int i) {
return hi(i) + ((R * t[i]) / G) * log(pr / p[i]);
}
/**
* Returns the geopotential altitude in meters of a given pressure in Pascals
*/
double geopotential_altitude(double pr) {
if (pr <= p[6]) { // Layer 6: Normal
return normal_layer(pr, 6);
} else if (pr <= p[5]) { // Layer 5: Normal
return normal_layer(pr, 5);
} else if (pr <= p[4]) { // Layer 4: Isothermic
return isothermic_layer(pr, 4);
} else if (pr <= p[3]) { // Layer 3: Normal
return normal_layer(pr, 3);
} else if (pr <= p[2]) { // Layer 2: Normal
return normal_layer(pr, 2);
} else if (pr <= p[1]) { // Layer 1: Isothermic
return isothermic_layer(pr, 1);
}
// Layer 0: Normal
return normal_layer(pr, 0);
}
/**
* Returns the geometric altitude for a given pressure
*
* Pressure in Pascals
* Altitude in meters
*/
double pressure_to_altitude(double pr) {
double height = geopotential_altitude(pr);
return (height * (RE * 1000)) / ((RE * 1000) - height);
}
/* #ifdef ALTITUDE_TEST */
/* #include <stdio.h> */
/* #include <stdlib.h> */
/* #define MAX_ERROR 10 */
/* void altitude_test(double altitude, uint32_t pressure) { */
/* double test_altitude = pressure_to_altitude(pressure); */
/* if (test_altitude > altitude - MAX_ERROR && */
/* test_altitude < altitude + MAX_ERROR) { // Success */
/* printf("%dPa = %gm (Expected %gm)\n", pressure, test_altitude, altitude); */
/* } else { // Fail */
/* printf("\nERROR:\n"); */
/* printf("%dPa = %gm (Expected %gm)\n", pressure, test_altitude, altitude); */
/* exit(1); */
/* } */
/* } */
/* int main(void) { */
/* printf("*** ALTITUDE_TEST ***\n\n"); */
/* printf("Data from Wolfram Alpha...\n\n"); */
/* altitude_test(-100, 102500); */
/* altitude_test( 0, 101300); */
/* altitude_test( 1000, 89880); */
/* altitude_test( 3000, 70120); */
/* altitude_test( 7000, 41110); */
/* altitude_test(11000, 22700); */
/* altitude_test(15000, 12110); */
/* altitude_test(20000, 5529); */
/* altitude_test(25000, 2549); */
/* altitude_test(30000, 1197); */
/* altitude_test(35000, 575); */
/* altitude_test(40000, 287); */
/* printf("\n*** DONE ***\n"); */
/* } */
/* #endif */

Wyświetl plik

@ -0,0 +1,37 @@
#ifndef __verification__
#define __verification__
#endif
/****************************//* barometric_altitude_tc *//****************************/
/**
* Write a description of your test case here
*/
#include "altitude.h"
/* Parameters in */
struct barometric_altitude_tc_params {
/* Input paramters to your test case go here */
float pressure; /* Pascals */
} barometric_altitude_tc_params;
/* Results out */
struct barometric_altitude_tc_results {
/* Result values should be populated here */
double altitude; /* meters */
} barometric_altitude_tc_results;
/* Function */
__verification__ void barometric_altitude_tc(void) {
/**
* The main body of the test case goes here.
*
* Use the input parameters to run the test case. Populate the
* results structure at the end
*/
barometric_altitude_tc_results.altitude =
pressure_to_altitude(barometric_altitude_tc_params.pressure);
}

Wyświetl plik

@ -0,0 +1,49 @@
#!/usr/bin/env python
# ------------------------------------------------------------------------------
# Imports
# ------------------------------------------------------------------------------
import sys
sys.path.append("./test")
import main
from random import normalvariate
# ------------------------------------------------------------------------------
# Test Script
# ------------------------------------------------------------------------------
class barometric_altitude_tc:
def __init__(self):
self.name = self.__class__.__name__
self.iterations = 25
def get_test(self):
"""Returns some suitable test parameters"""
params = main.struct_barometric_altitude_tc_params()
"""
Assign input parameters here
"""
# Random barometeric pressure
params.pressure = abs(normalvariate(0, 80*1000))
return params
def is_correct(self, params, result, print_info):
"""Returns if a result is correct for the given parameters"""
"""
Compare result and params here, decide sth.
Can use print_info
"""
altitude = result['altitude']
print_info("Pressure: {:.1f} Pa, Altitude: {:.2f} meters".format(
params.pressure, float(altitude)))
print_info("")
return True

Wyświetl plik

@ -49,6 +49,7 @@
#include "adc_battery_solar_read.h"
#include "gps_baud_error.h"
#include "crc32_gen_buf.h"
#include "barometric_altitude.h"
/* [new_tc] */