diff options
| -rw-r--r-- | src/Makefile | 5 | ||||
| -rw-r--r-- | src/kernel/ao_convert_pa.c | 4 | ||||
| -rw-r--r-- | src/util/make-altitude-pa | 184 | 
3 files changed, 115 insertions, 78 deletions
| diff --git a/src/Makefile b/src/Makefile index df7a31ee..a7a26b26 100644 --- a/src/Makefile +++ b/src/Makefile @@ -98,7 +98,7 @@ uninstall:  all-recursive: all-local -all-local: altitude.h altitude-pa.h ao_kalman.h ao_whiten.h $(PDCLIB) +all-local: altitude.h altitude-pa.h altitude-pa-small.h ao_kalman.h ao_whiten.h $(PDCLIB)  altitude.h: make-altitude  	nickle $< > $@ @@ -106,6 +106,9 @@ altitude.h: make-altitude  altitude-pa.h: make-altitude-pa  	nickle $< > $@ +altitude-pa-small.h: make-altitude-pa +	nickle $< --sample 3 > $@ +  ao_kalman.h: make-kalman kalman.5c kalman_filter.5c load_csv.5c matrix.5c  	bash $< kalman > $@ diff --git a/src/kernel/ao_convert_pa.c b/src/kernel/ao_convert_pa.c index fe6e0ef6..20162c1f 100644 --- a/src/kernel/ao_convert_pa.c +++ b/src/kernel/ao_convert_pa.c @@ -24,7 +24,11 @@  #endif  static const alt_t altitude_table[] AO_CONST_ATTRIB = { +#if AO_SMALL_ALTITUDE_TABLE +#include "altitude-pa-small.h" +#else  #include "altitude-pa.h" +#endif  };  #ifndef FETCH_ALT diff --git a/src/util/make-altitude-pa b/src/util/make-altitude-pa index 22831d50..d36f3f41 100644 --- a/src/util/make-altitude-pa +++ b/src/util/make-altitude-pa @@ -185,105 +185,135 @@ line_t best_fit(real[] values, int first, int last) {         return (line_t) { m = m, b = b };  } -real	min_Pa = 0; -real	max_Pa = 120000; +void print_table (int pa_sample_shift, int pa_part_shift) +{ +	real	min_Pa = 0; +	real	max_Pa = 120000; -/* Target is an array of < 1000 entries */ -int pa_sample_shift = 2; -int pa_part_shift = 6; -int pa_part_mask = (1 << pa_part_shift) - 1; +	int pa_part_mask = (1 << pa_part_shift) - 1; -int num_part = ceil(max_Pa / (2 ** (pa_part_shift + pa_sample_shift))); +	int num_part = ceil(max_Pa / (2 ** (pa_part_shift + pa_sample_shift))); -int num_samples = num_part << pa_part_shift; +	int num_samples = num_part << pa_part_shift; -real sample_to_Pa(int sample) = sample << pa_sample_shift; +	real sample_to_Pa(int sample) = sample << pa_sample_shift; -real sample_to_altitude(int sample) = pressure_to_altitude(sample_to_Pa(sample)); +	real sample_to_altitude(int sample) = pressure_to_altitude(sample_to_Pa(sample)); -int part_to_sample(int part) = part << pa_part_shift; +	int part_to_sample(int part) = part << pa_part_shift; -int sample_to_part(int sample) = sample >> pa_part_shift; +	int sample_to_part(int sample) = sample >> pa_part_shift; -bool is_part(int sample) = (sample & pa_part_mask) == 0; +	bool is_part(int sample) = (sample & pa_part_mask) == 0; -real[num_samples] alt = { [n] = sample_to_altitude(n) }; +	real[num_samples] alt = { [n] = sample_to_altitude(n) }; -int seg_len = 1 << pa_part_shift; +	int seg_len = 1 << pa_part_shift; -line_t [num_part] fit = { -	[n] = best_fit(alt, n * seg_len, n * seg_len + seg_len - 1) -}; - -real[num_samples/seg_len + 1]	alt_part; -real[dim(alt_part)]		alt_error = {0...}; - -alt_part[0] = fit[0].b; -alt_part[dim(fit)] = fit[dim(fit)-1].m * dim(fit) * seg_len + fit[dim(fit)-1].b; +	line_t [num_part] fit = { +		[n] = best_fit(alt, n * seg_len, n * seg_len + seg_len - 1) +	}; -for (int i = 0; i < dim(fit) - 1; i++) { -	real	here, there; -	here = fit[i].m * (i+1) * seg_len + fit[i].b; -	there = fit[i+1].m * (i+1) * seg_len + fit[i+1].b; -#	printf ("at %d mis-fit %8.2f\n", i, there - here); -	alt_part[i+1] = (here + there) / 2; -} +	real[num_samples/seg_len + 1]	alt_part; +	real[dim(alt_part)]		alt_error = {0...}; -real round(real x) = floor(x + 0.5); +	alt_part[0] = fit[0].b; +	alt_part[dim(fit)] = fit[dim(fit)-1].m * dim(fit) * seg_len + fit[dim(fit)-1].b; -real sample_to_fit_altitude(int sample) { -	int	sub = sample // seg_len; -	int	off = sample % seg_len; -	line_t	l = fit[sub]; -	real r_v; -	real i_v; +	for (int i = 0; i < dim(fit) - 1; i++) { +		real	here, there; +		here = fit[i].m * (i+1) * seg_len + fit[i].b; +		there = fit[i+1].m * (i+1) * seg_len + fit[i+1].b; +#		printf ("at %d mis-fit %8.2f\n", i, there - here); +		alt_part[i+1] = (here + there) / 2; +	} -	r_v = sample * l.m + l.b; -	i_v = (round(alt_part[sub]*10) * (seg_len - off) + round(alt_part[sub+1]*10) * off) / seg_len; -	return i_v/10; -} +	real round(real x) = floor(x + 0.5); -real max_error = 0; -int max_error_sample = 0; -real total_error = 0; +	real sample_to_fit_altitude(int sample) { +		int	sub = sample // seg_len; +			int	off = sample % seg_len; +		line_t	l = fit[sub]; +		real r_v; +		real i_v; -for (int sample = 0; sample < num_samples; sample++) { -	real	Pa = sample_to_Pa(sample); -	real	meters = alt[sample]; +		r_v = sample * l.m + l.b; +		i_v = (round(alt_part[sub]*10) * (seg_len - off) + round(alt_part[sub+1]*10) * off) / seg_len; +		return i_v/10; +	} -	real	meters_approx = sample_to_fit_altitude(sample); -	real	error = abs(meters - meters_approx); +	real max_error = 0; +	int max_error_sample = 0; +	real total_error = 0; + +	for (int sample = 0; sample < num_samples; sample++) { +		real	Pa = sample_to_Pa(sample); +		real	meters = alt[sample]; + +		real	meters_approx = sample_to_fit_altitude(sample); +		real	error = abs(meters - meters_approx); + +		int	part = sample_to_part(sample); + +		if (error > alt_error[part]) +			alt_error[part] = error; + +		total_error += error; +		if (error > max_error) { +			max_error = error; +			max_error_sample = sample; +		} +		if (false) { +			printf ("	%8.1f %8.2f %8.2f %8.2f %s\n", +				Pa, +				meters, +				meters_approx, +				meters - meters_approx, +				is_part(sample) ? "*" : ""); +		} +	} -	int	part = sample_to_part(sample); +	printf ("/*max error %f at %7.3f kPa. Average error %f*/\n", +		max_error, sample_to_Pa(max_error_sample) / 1000, total_error / num_samples); -	if (error > alt_error[part]) -		alt_error[part] = error; +	printf ("#define NALT %d\n", dim(alt_part)); +	printf ("#define ALT_SHIFT %d\n", pa_part_shift + pa_sample_shift); +	printf ("#ifndef AO_ALT_VALUE\n#define AO_ALT_VALUE(x) (alt_t) (x)\n#endif\n"); -	total_error += error; -	if (error > max_error) { -		max_error = error; -		max_error_sample = sample; -	} -	if (false) { -		printf ("	%8.1f %8.2f %8.2f %8.2f %s\n", -			Pa, -			meters, -			meters_approx, -			meters - meters_approx, -			is_part(sample) ? "*" : ""); +	for (int part = 0; part < dim(alt_part); part++) { +		real kPa = sample_to_Pa(part_to_sample(part)) / 1000; +		printf ("AO_ALT_VALUE(%10.1f), /* %6.2f kPa error %6.2fm */\n", +			round (alt_part[part]*10) / 10, kPa, +			alt_error[part]);  	}  } -printf ("/*max error %f at %7.3f kPa. Average error %f*/\n", -	max_error, sample_to_Pa(max_error_sample) / 1000, total_error / num_samples); - -printf ("#define NALT %d\n", dim(alt_part)); -printf ("#define ALT_SHIFT %d\n", pa_part_shift + pa_sample_shift); -printf ("#ifndef AO_ALT_VALUE\n#define AO_ALT_VALUE(x) (alt_t) (x)\n#endif\n"); - -for (int part = 0; part < dim(alt_part); part++) { -	real kPa = sample_to_Pa(part_to_sample(part)) / 1000; -	printf ("AO_ALT_VALUE(%10.1f), /* %6.2f kPa error %6.2fm */\n", -		round (alt_part[part]*10) / 10, kPa, -		alt_error[part]); +autoload ParseArgs; + +void main() +{ +	/* Target is an array of < 1000 entries */ +	int pa_sample_shift = 2; +	int pa_part_shift = 6; + +	ParseArgs::argdesc argd = { +		.args = { +			{ .var = { .arg_int = &pa_sample_shift }, +			  .abbr = 's', +			  .name = "sample", +			  .expr_name = "sample_shift", +			  .desc = "sample shift value" }, +			{ .var = { .arg_int = &pa_part_shift }, +			  .abbr = 'p', +			  .name = "part", +			  .expr_name = "part_shift", +			  .desc = "part shift value" }, +		} +	}; + +	ParseArgs::parseargs(&argd, &argv); + +	print_table(pa_sample_shift, pa_part_shift);  } + +main(); | 
