fixed radius and lat/lon calculation

- fixed the unit test for it
- got rid of `ceilf()` and `log2f()`
This commit is contained in:
Wojciech Kaczmarski 2026-01-18 12:49:08 +01:00
parent 0ee873c82b
commit de6cd79146
3 changed files with 44 additions and 17 deletions

2
m17.h
View file

@ -15,7 +15,7 @@ extern "C" {
#include <time.h>
#include <math.h>
#define LIBM17_VERSION "1.1.7"
#define LIBM17_VERSION "1.1.8"
// M17 C library - syncword, payload, and frame sizes in symbols
#define SYM_PER_SWD 8 //symbols per syncword

View file

@ -87,12 +87,21 @@ void set_LSF_meta_position(lsf_t *lsf, const uint8_t data_source, const uint8_t
tmp[0] = (data_source<<4) | station_type;
tmp[1] |= validity<<4; //gnss data validity field
uint8_t log_r;
if(radius==0)
log_r = 0;
else
log_r = (uint8_t)M17_MAX(ceilf(log2f(radius)), 0);
log_r = (log_r>7) ? 7 : log_r; //limit log2(r) to 7
static const float radius_lut[8] =
{
1.0f, 2.0f, 4.0f, 8.0f,
16.0f, 32.0f, 64.0f, 128.0f
};
uint8_t log_r = 7;
for (uint8_t i = 0; i < 8; i++)
{
if (radius < radius_lut[i])
{
log_r = i;
break;
}
}
tmp[1] |= log_r<<1; //log2 radius
tmp[1] |= (bearing>>8)&1; //bearing MSB
@ -102,11 +111,13 @@ void set_LSF_meta_position(lsf_t *lsf, const uint8_t data_source, const uint8_t
lat_tmp = lat/90.0f * 8388607.0f;
lon_tmp = lon/180.0f * 8388607.0f;
for(uint8_t i=0; i<3; i++)
{
tmp[3+i] = *((uint8_t*)&lat_tmp+2-i);
tmp[6+i] = *((uint8_t*)&lon_tmp+2-i);
}
tmp[3] = (lat_tmp >> 16) & 0xFF;
tmp[4] = (lat_tmp >> 8) & 0xFF;
tmp[5] = lat_tmp & 0xFF;
tmp[6] = (lon_tmp >> 16) & 0xFF;
tmp[7] = (lon_tmp >> 8) & 0xFF;
tmp[8] = lon_tmp & 0xFF;
uint16_t alt = roundf((500.0f + altitude)*2.0f); //altitude
tmp[9] = alt>>8;

View file

@ -1087,16 +1087,32 @@ void meta_position(void)
int retval = get_LSF_meta_position(&data_source_n, &station_type_n, &lat_n, &lon_n, &flags_n, &altitude_n, &bearing_n, &speed_n, &radius_n, &lsf);
static const float radius_lut[8] =
{
1.0f, 2.0f, 4.0f, 8.0f,
16.0f, 32.0f, 64.0f, 128.0f
};
uint8_t q = 7;
for (uint8_t i = 0; i < 8; i++)
{
if (radius < radius_lut[i])
{
q = i;
break;
}
}
TEST_ASSERT_EQUAL_INT8(0, retval);
TEST_ASSERT_EQUAL_UINT8(data_source, data_source_n);
TEST_ASSERT_EQUAL_UINT8(station_type, station_type_n);
TEST_ASSERT(fabsf(lat-lat_n) < 0.001f);
TEST_ASSERT(fabsf(lon-lon_n) < 0.001f);
TEST_ASSERT_FLOAT_WITHIN(0.001f, lat, lat_n);
TEST_ASSERT_FLOAT_WITHIN(0.001f, lon, lon_n);
TEST_ASSERT_EQUAL_UINT8(flags, flags_n);
TEST_ASSERT(fabsf(altitude-altitude_n) < 0.001f);
TEST_ASSERT_FLOAT_WITHIN(0.001f, altitude, altitude_n);
TEST_ASSERT_EQUAL_UINT16(bearing, bearing_n);
TEST_ASSERT(fabsf(speed-speed_n) < 0.001f);
TEST_ASSERT(fabsf(powf(2.0f, ceil(log2f(radius)))-radius_n) < 0.001f);
TEST_ASSERT_FLOAT_WITHIN(0.001f, speed, speed_n);
TEST_ASSERT_FLOAT_WITHIN(0.001f, radius_lut[q], radius_n);
}
void crc_checks(void)