diff --git a/firmware/inc/location.h b/firmware/inc/location.h index 34741a7..7f66ea5 100644 --- a/firmware/inc/location.h +++ b/firmware/inc/location.h @@ -29,11 +29,10 @@ #include "samd20.h" bool telemetry_location_tx_allow(void); -void telemetry_location_update(int32_t lon_i, int32_t lat_i); +void telemetry_location_update(int32_t lon_hn, int32_t lat_hn); -bool latlon_in_aprs_zone(int32_t aprs_zone, int32_t aprs_zone_outline, float lon, float lat); bool aprs_location_tx_allow(void); int32_t aprs_location_frequency(void); -void aprs_location_update(int32_t lon_i, int32_t lat_i); +void aprs_location_update(int32_t lon_hn, int32_t lat_hn); #endif /* LOCATION_H */ diff --git a/firmware/src/location.c b/firmware/src/location.c index 8b79149..b4e4104 100644 --- a/firmware/src/location.c +++ b/firmware/src/location.c @@ -73,11 +73,13 @@ bool point_in_polygon(const int32_t* poly, uint32_t points, int32_t x, int32_t y } /** * Returns if a latitude and longitude is in a polygon + * + * lat_hn, lon_hn in 100 nanodeg */ -bool latlon_in_polygon(const int32_t* poly, uint32_t points, float lon, float lat) +bool latlon_in_polygon(const int32_t* poly, uint32_t points, int32_t lon_hn, int32_t lat_hn) { - int32_t x = (int32_t)round(lon * 1000 * 1000); // longitude: µdegrees - int32_t y = (int32_t)round(lat * 1000 * 1000); // latitude: µdegrees + int32_t x = lon_hn / 10; /* longitude : 100 nano -> µdegrees */ + int32_t y = lat_hn / 10; /* latitude : 100 nano -> µdegrees */ return point_in_polygon(poly, points, x, y); } @@ -90,13 +92,15 @@ bool latlon_in_polygon(const int32_t* poly, uint32_t points, float lon, float la /** * Returns if a latitude and longitude is in a given no telem outline + * + * lat_hn, lon_hn in 100 nanodeg */ -bool latlon_in_no_telem_zone(int32_t no_telem_outline, float lon, float lat) +bool latlon_in_no_telem_zone(int32_t no_telem_outline, int32_t lon_hn, int32_t lat_hn) { return latlon_in_polygon( no_telem_outlines[no_telem_outline], no_telem_outline_lengths[no_telem_outline], - lon, lat); + lon_hn, lat_hn); } /** * Return if telemetry should be transmitted in the current zone @@ -109,19 +113,17 @@ bool telemetry_location_tx_allow(void) /** * Updates the current telemetry location based on the current lat/lon * - * lat_i, lon_i in 100 nanodeg + * lat_hn, lon_hn in 100 nanodeg */ -void telemetry_location_update(int32_t lon_i, int32_t lat_i) +void telemetry_location_update(int32_t lon_hn, int32_t lat_hn) { uint32_t outline; - float lat = lat_i / 10000000.0; /* degrees */ - float lon = lon_i / 10000000.0; /* degrees */ /* Were we in a telemetry outline last time? */ if (current_no_telem_outline >= 0) { /* Are we still in this outline? */ - if (latlon_in_no_telem_zone(current_no_telem_outline, lon, lat)) { + if (latlon_in_no_telem_zone(current_no_telem_outline, lon_hn, lat_hn)) { return; /* Still in this outline */ } } @@ -130,7 +132,7 @@ void telemetry_location_update(int32_t lon_i, int32_t lat_i) while (sizeof(no_telem_outlines)/sizeof(int32_t*) != 6); for (outline = 0; outline < sizeof(no_telem_outlines) / sizeof(int32_t*); outline++) { - if (latlon_in_no_telem_zone(outline, lon, lat)) { /* If we're in this zone */ + if (latlon_in_no_telem_zone(outline, lon_hn, lat_hn)) { /* If we're in this zone */ /* Record the current outline */ current_no_telem_outline = outline; @@ -146,13 +148,16 @@ void telemetry_location_update(int32_t lon_i, int32_t lat_i) /** * Returns if a latitude and longitude is in a given aprs zone outline + * + * lat_hn, lon_hn in 100 nanodeg */ -bool latlon_in_aprs_zone(int32_t aprs_zone, int32_t aprs_zone_outline, float lon, float lat) +bool latlon_in_aprs_zone(int32_t aprs_zone, int32_t aprs_zone_outline, + int32_t lon_hn, int32_t lat_hn) { return latlon_in_polygon( aprs_zones[aprs_zone].outlines[aprs_zone_outline], aprs_zones[aprs_zone].outline_lengths[aprs_zone_outline], - lon, lat); + lon_hn, lat_hn); } /** * Returns if aprs should be transmitted in the current zone @@ -178,13 +183,11 @@ int32_t aprs_location_frequency(void) /** * Updates the aprs location based on the current lat/lon * - * lat_i, lon_i in 100 nanodeg + * lat_hn, lon_hn in 100 nanodeg */ -void aprs_location_update(int32_t lat_i, int32_t lon_i) +void aprs_location_update(int32_t lon_hn, int32_t lat_hn) { uint32_t z, outline; - float lat = lat_i / 10000000.0; /* degrees */ - float lon = lon_i / 10000000.0; /* degrees */ /* Were we in an aprs zone last time? */ if (current_aprs_zone >= 0 && current_aprs_zone_outline >= 0) { @@ -192,7 +195,7 @@ void aprs_location_update(int32_t lat_i, int32_t lon_i) /* Are we still in the outline? */ if (latlon_in_aprs_zone(current_aprs_zone, current_aprs_zone_outline, - lon, lat)) { /* Still in outline */ + lon_hn, lat_hn)) { /* Still in outline */ return; } } @@ -202,7 +205,7 @@ void aprs_location_update(int32_t lat_i, int32_t lon_i) for (outline = 0; outline < aprs_zones[z].outline_count; outline++) { - if (latlon_in_aprs_zone(z, outline, lon, lat)) { /* If we're in this zone */ + if (latlon_in_aprs_zone(z, outline, lon_hn, lat_hn)) { /* If we're in this zone */ /* Record the current zone */ current_aprs_zone = z; diff --git a/firmware/test/tc/location_aprs.h b/firmware/test/tc/location_aprs.h index 10a10e3..283d259 100644 --- a/firmware/test/tc/location_aprs.h +++ b/firmware/test/tc/location_aprs.h @@ -21,7 +21,11 @@ struct location_aprs_tc_results { /* Function */ __verification__ void location_aprs_tc(void) { - aprs_location_update(location_aprs_tc_params.lon, location_aprs_tc_params.lat); + /* Supply co-ords in units of 100 nanodeg */ + aprs_location_update( + (int32_t)(location_aprs_tc_params.lon * 10 * 1000 * 1000), + (int32_t)(location_aprs_tc_params.lat * 10 * 1000 * 1000) + ); location_aprs_tc_results.tx_allow = aprs_location_tx_allow(); location_aprs_tc_results.frequency = aprs_location_frequency(); diff --git a/firmware/test/tc/location_telemetry.h b/firmware/test/tc/location_telemetry.h index f78bd1b..f37e148 100644 --- a/firmware/test/tc/location_telemetry.h +++ b/firmware/test/tc/location_telemetry.h @@ -20,7 +20,11 @@ struct location_telemetry_tc_results { /* Function */ __verification__ void location_telemetry_tc(void) { - telemetry_location_update(location_telemetry_tc_params.lon, location_telemetry_tc_params.lat); + /* Supply co-ords in units of 100 nanodeg */ + telemetry_location_update( + (int32_t)(location_telemetry_tc_params.lon * 10 * 1000 * 1000), + (int32_t)(location_telemetry_tc_params.lat * 10 * 1000 * 1000) + ); location_telemetry_tc_results.tx_allow = telemetry_location_tx_allow(); } diff --git a/firmware/test/tc/location_telemetry.py b/firmware/test/tc/location_telemetry.py index d2ff5ba..3ebad1a 100644 --- a/firmware/test/tc/location_telemetry.py +++ b/firmware/test/tc/location_telemetry.py @@ -62,6 +62,6 @@ class location_telemetry_tc: else: print_info("{} ({:.1f}, {:.1f}): Expected {}, Geofence {}".format( name, params.lat, params.lon, - "Permitted" if expeced_tx_allow else "Not Permitted", + "Permitted" if expected_tx_allow else "Not Permitted", "Permitted" if tx_allow else "Not Permitted")) return False