Porównaj commity

...

8 Commity

Autor SHA1 Wiadomość Data
Wojciech Kaczmarski 55ce31bf63
Merge 7966143ba0 into d43dd57031 2024-04-26 22:41:02 +02:00
Morgan Diepart d43dd57031 Module17 Fixed Baseband tuning potentiometer setting 2024-04-26 21:20:08 +02:00
Marco 70f0ce45d3 GPS: using 16-bit integers for course over ground 2024-04-10 19:12:34 +02:00
Marco a17ad80f10 GPS: using 16-bit integers for altitude and speed 2024-04-10 19:12:34 +02:00
Marco e4a62f30ee GPS: using fixed-point 32-bit value for latitude and longitude 2024-04-10 19:12:34 +02:00
Marco 36ef3b310c Added function to convert minmea coordinate to fixed-point integer representation 2024-04-10 08:04:26 +02:00
Wojciech Kaczmarski 7966143ba0
Update PwmCompensator.hpp
Cosmetic changes.
2024-02-19 12:05:39 +01:00
Wojciech Kaczmarski e4cf2e33d9
Update PwmCompensator.hpp
Corrected TYT MD-380 PWM compensator IIR filter's gain and improved the way to store its taps in code (no more compile-time division, improved readability).
2024-02-19 11:18:30 +01:00
12 zmienionych plików z 153 dodań i 58 usunięć

Wyświetl plik

@ -80,6 +80,8 @@ jobs:
run: meson test -C build "M17 RRC Test"
- name: Codeplug Test
run: meson test -C build "Codeplug Test"
- name: minmea Conversion Test
run: meson test -C build "minmea conversion Test"
# The following tests are disabled because they appear to be flakey when run in CI
# - name: Sine Test
# run: meson test -C build "Sine Test"

Wyświetl plik

@ -252,6 +252,25 @@ static inline float minmea_tocoord(struct minmea_float *f)
return (float) degrees + (float) minutes / (60 * f->scale);
}
/**
* Convert a raw coordinate to a fixed point value.
* Returns zero for "unknown" values.
*/
int minmea_tofixedpoint(struct minmea_float *f);
/**
* Convert a fixed-point value to an integer value.
* Returns zero for "unknown" values.
*/
static inline int minmea_toint(struct minmea_float *f)
{
if(f->scale == 0)
return 0;
return f->value / f->scale;
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -642,4 +642,20 @@ int minmea_gettime(struct timespec *ts, const struct minmea_date *date, const st
}
}
int minmea_tofixedpoint(struct minmea_float *f) {
if (f->scale == 0)
return 0;
int32_t value = f->value;
int32_t scale = f->scale;
int8_t sign = value < 0 ? -1 : 1;
// Ensure value is always positive
value = value * sign;
int32_t coord_int = value / (scale * 100);
int32_t coord_dec = (value % (scale * 100)) * (100000 / scale) / 6;
return (coord_int * 1000000 + coord_dec) * sign;
}
/* vim: set ts=4 sw=4 et: */

Wyświetl plik

@ -880,6 +880,10 @@ vp_test = executable('vp_test',
sources : unit_test_src + ['tests/unit/voice_prompts.c'],
kwargs : unit_test_opts)
minmea_conversion_test = executable('minmea_conversion_test',
sources : unit_test_src + ['tests/unit/convert_minmea_coord.c'],
kwargs : unit_test_opts)
test('M17 Golay Unit Test', m17_golay_test)
test('M17 Viterbi Unit Test', m17_viterbi_test)
## test('M17 Demodulator Test', m17_demodulator_test) # Skipped for now as this test no longer works after an M17 refactor
@ -888,3 +892,4 @@ test('Codeplug Test', cps_test)
test('Linux InputStream Test', linux_inputStream_test)
test('Sine Test', sine_test)
## test('Voice Prompts Test', vp_test) # Skipped for now as this test no longer works
test('minmea conversion Test', minmea_conversion_test)

Wyświetl plik

@ -22,6 +22,7 @@
#include <datetime.h>
#include <stdint.h>
#include <minmea.h>
/**
* Data structure representing a single satellite as part of a GPS fix.
@ -47,12 +48,12 @@ typedef struct
uint8_t satellites_in_view; // Satellites in view
gpssat_t satellites[12]; // Details about satellites in view
uint32_t active_sats; // Bitmap representing which sats are part of the fix
float latitude; // Latitude coordinates
float longitude; // Longitude coordinates
float altitude; // Antenna altitude above mean sea level (geoid) in m
float speed; // Ground speed in km/h
float tmg_mag; // Course over ground, degrees, magnetic
float tmg_true; // Course over ground, degrees, true
int32_t latitude; // Latitude coordinates
int32_t longitude; // Longitude coordinates
int16_t altitude; // Antenna altitude above mean sea level (geoid) in m
uint16_t speed; // Ground speed in km/h
int16_t tmg_mag; // Course over ground, degrees, magnetic
int16_t tmg_true; // Course over ground, degrees, true
}
gps_t;
@ -63,4 +64,5 @@ gps_t;
*/
void gps_task();
#endif /* GPS_H */

Wyświetl plik

@ -59,11 +59,11 @@ public:
float operator()(const float& input)
{
u[0] = input;
y[0] = (a/d)*(u[0])
+ (b/d)*(u[1])
+ (c/d)*(u[2])
- (e/d)*(y[1])
- (f/d)*(y[2]);
y[0] = b[0] * u[0]
+ b[1] * u[1]
+ b[2] * u[2]
- a[1] * y[1]
- a[2] * y[2];
for(size_t i = 2; i > 0; i--)
{
@ -71,7 +71,7 @@ public:
y[i] = y[i - 1];
}
return y[0] * 0.5f;
return y[0];
}
/**
@ -85,12 +85,13 @@ public:
private:
static constexpr float a = 4982680082321166792352.0f;
static constexpr float b = -6330013275146484168000.0f;
static constexpr float c = 1871109008789062500000.0f;
static constexpr float d = 548027992248535162477.0f;
static constexpr float e = -24496793746948241250.0f;
static constexpr float f = 244617462158203125.0f;
static constexpr float b[3]={
4.098580379420818f, -5.206850085165959f, 1.539109584496514f
};
static constexpr float a[3]={
0.0f, -0.044699895066380f, 0.000446359429843f
};
std::array< float, 3 > u; ///< History of past inputs.
std::array< float, 3 > y; ///< History of past outputs.

Wyświetl plik

@ -26,7 +26,7 @@
#include <string.h>
#include <stdbool.h>
#define KNOTS2KMH 1.852f
#define KNOTS2KMH(x) ((((int) x) * 1852) / 1000)
static char sentence[2*MINMEA_MAX_LENGTH];
static bool gpsEnabled = false;
@ -90,8 +90,8 @@ void gps_task()
struct minmea_sentence_rmc frame;
if (minmea_parse_rmc(&frame, sentence))
{
gps_data.latitude = minmea_tocoord(&frame.latitude);
gps_data.longitude = minmea_tocoord(&frame.longitude);
gps_data.latitude = minmea_tofixedpoint(&frame.latitude);
gps_data.longitude = minmea_tofixedpoint(&frame.longitude);
gps_data.timestamp.hour = frame.time.hours;
gps_data.timestamp.minute = frame.time.minutes;
gps_data.timestamp.second = frame.time.seconds;
@ -102,7 +102,7 @@ void gps_task()
}
gps_data.tmg_true = minmea_tofloat(&frame.course);
gps_data.speed = minmea_tofloat(&frame.speed) * KNOTS2KMH;
gps_data.speed = KNOTS2KMH(minmea_toint(&frame.speed));
}
break;
@ -113,7 +113,7 @@ void gps_task()
{
gps_data.fix_quality = frame.fix_quality;
gps_data.satellites_tracked = frame.satellites_tracked;
gps_data.altitude = minmea_tofloat(&frame.altitude);
gps_data.altitude = minmea_toint(&frame.altitude);
}
}
break;
@ -166,9 +166,9 @@ void gps_task()
struct minmea_sentence_vtg frame;
if (minmea_parse_vtg(&frame, sentence))
{
gps_data.speed = minmea_tofloat(&frame.speed_kph);
gps_data.tmg_mag = minmea_tofloat(&frame.magnetic_track_degrees);
gps_data.tmg_true = minmea_tofloat(&frame.true_track_degrees);
gps_data.speed = minmea_toint(&frame.speed_kph);
gps_data.tmg_mag = minmea_toint(&frame.magnetic_track_degrees);
gps_data.tmg_true = minmea_toint(&frame.true_track_degrees);
}
}
break;

Wyświetl plik

@ -30,6 +30,7 @@
#include <stdlib.h>
#include <string.h>
#include <utils.h>
#include <inttypes.h>
#include <ui/ui_default.h>
#include <beeps.h>
#include "interfaces/cps_io.h"
@ -549,7 +550,7 @@ void vp_announceM17Info(const channel_t* channel, bool isEditing,
static bool IsCompassCloseEnoughToCardinalPoint()
{
float tmg_true = state.gps_data.tmg_true;
int16_t tmg_true = state.gps_data.tmg_true;
return (tmg_true < (0 + margin) || tmg_true > (360 - margin)) || // north
(tmg_true > (90 - margin) && tmg_true < (90 + margin)) || // east
@ -637,7 +638,7 @@ void vp_announceGPSInfo(vpGPSInfoFlags_t gpsInfoFlags)
vp_queuePrompt(PROMPT_COMPASS);
if (!IsCompassCloseEnoughToCardinalPoint())
{
sniprintf(buffer, 16, "%3.1f", state.gps_data.tmg_true);
sniprintf(buffer, 16, "%d", state.gps_data.tmg_true);
vp_queueString(buffer, vpAnnounceCommonSymbols);
vp_queuePrompt(PROMPT_DEGREES);
}
@ -672,7 +673,7 @@ void vp_announceGPSInfo(vpGPSInfoFlags_t gpsInfoFlags)
if ((gpsInfoFlags & vpGPSSpeed) != 0)
{
// speed/altitude:
sniprintf(buffer, 16, "%4.1fkm/h", state.gps_data.speed);
sniprintf(buffer, 16, "%dkm/h", state.gps_data.speed);
vp_queuePrompt(PROMPT_SPEED);
vp_queueString(buffer, vpAnnounceCommonSymbols |
vpAnnounceLessCommonSymbols);
@ -682,27 +683,33 @@ void vp_announceGPSInfo(vpGPSInfoFlags_t gpsInfoFlags)
{
vp_queuePrompt(PROMPT_ALTITUDE);
sniprintf(buffer, 16, "%4.1fm", state.gps_data.altitude);
sniprintf(buffer, 16, "%dm", state.gps_data.altitude);
vp_queueString(buffer, vpAnnounceCommonSymbols);
addSilenceIfNeeded(flags);
}
if ((gpsInfoFlags & vpGPSLatitude) != 0)
{
// lat/long
sniprintf(buffer, 16, "%8.6f", state.gps_data.latitude);
// Convert from signed longitude, to unsigned + direction
int32_t latitude = abs(state.gps_data.latitude);
uint8_t latitude_int = latitude / 1000000;
int32_t latitude_dec = latitude % 1000000;
voicePrompt_t direction = (state.gps_data.latitude < 0) ? PROMPT_SOUTH : PROMPT_NORTH;
sniprintf(buffer, 16, "%d.%06"PRId32, latitude_int, latitude_dec);
stripTrailingZeroes(buffer);
vp_queuePrompt(PROMPT_LATITUDE);
vp_queueString(buffer, vpAnnounceCommonSymbols);
vp_queuePrompt(PROMPT_NORTH);
vp_queuePrompt(direction);
}
if ((gpsInfoFlags & vpGPSLongitude) != 0)
{
float longitude = state.gps_data.longitude;
voicePrompt_t direction = (longitude < 0) ? PROMPT_WEST : PROMPT_EAST;
longitude = (longitude < 0) ? -longitude : longitude;
sniprintf(buffer, 16, "%8.6f", longitude);
// Convert from signed longitude, to unsigned + direction
int32_t longitude = abs(state.gps_data.longitude);
uint8_t longitude_int = longitude / 1000000;
int32_t longitude_dec = longitude % 1000000;
voicePrompt_t direction = (state.gps_data.longitude < 0) ? PROMPT_WEST : PROMPT_EAST;
sniprintf(buffer, 16, "%d.%06"PRId32, longitude_int, longitude_dec);
stripTrailingZeroes(buffer);
vp_queuePrompt(PROMPT_LONGITUDE);

Wyświetl plik

@ -63,6 +63,7 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#include <ui/ui_default.h>
#include <rtx.h>
@ -1269,12 +1270,12 @@ void ui_saveState()
}
#ifdef CONFIG_GPS
static float priorGPSSpeed = 0;
static float priorGPSAltitude = 0;
static float priorGPSDirection = 500; // impossible value init.
static uint8_t priorGPSFixQuality= 0;
static uint8_t priorGPSFixType = 0;
static uint8_t priorSatellitesInView = 0;
static uint16_t priorGPSSpeed = 0;
static int16_t priorGPSAltitude = 0;
static int16_t priorGPSDirection = 500; // impossible value init.
static uint8_t priorGPSFixQuality= 0;
static uint8_t priorGPSFixType = 0;
static uint8_t priorSatellitesInView = 0;
static uint32_t vpGPSLastUpdate = 0;
static vpGPSInfoFlags_t GetGPSDirectionOrSpeedChanged()
@ -1300,22 +1301,19 @@ static vpGPSInfoFlags_t GetGPSDirectionOrSpeedChanged()
priorGPSFixType = state.gps_data.fix_type;
}
float speedDiff=fabs(state.gps_data.speed - priorGPSSpeed);
if (speedDiff >= 1)
if (state.gps_data.speed != priorGPSSpeed)
{
whatChanged |= vpGPSSpeed;
priorGPSSpeed = state.gps_data.speed;
}
float altitudeDiff = fabs(state.gps_data.altitude - priorGPSAltitude);
if (altitudeDiff >= 5)
if (state.gps_data.altitude != priorGPSAltitude)
{
whatChanged |= vpGPSAltitude;
priorGPSAltitude = state.gps_data.altitude;
}
float degreeDiff = fabs(state.gps_data.tmg_true - priorGPSDirection);
if (degreeDiff >= 1)
if (state.gps_data.tmg_true != priorGPSDirection)
{
whatChanged |= vpGPSDirection;
priorGPSDirection = state.gps_data.tmg_true;

Wyświetl plik

@ -682,22 +682,32 @@ void _ui_drawMenuGPS()
}
gfx_print(layout.line1_pos, layout.top_font, TEXT_ALIGN_LEFT,
color_white, fix_buf);
// Convert from signed longitude, to unsigned + direction
int32_t latitude = abs(last_state.gps_data.latitude);
uint8_t latitude_int = latitude / 1000000;
int32_t latitude_dec = latitude % 1000000;
char *direction_lat = (last_state.gps_data.latitude < 0) ? "S " : "N ";
gfx_print(layout.line1_pos, layout.top_font, TEXT_ALIGN_CENTER,
color_white, "N ");
color_white, direction_lat);
gfx_print(layout.line1_pos, layout.top_font, TEXT_ALIGN_RIGHT,
color_white, "%8.6f", last_state.gps_data.latitude);
color_white, "%d.%.6d", latitude_int, latitude_dec);
gfx_print(layout.line2_pos, layout.top_font, TEXT_ALIGN_LEFT,
color_white, type_buf);
// Convert from signed longitude, to unsigned + direction
float longitude = last_state.gps_data.longitude;
char *direction = (longitude < 0) ? "W " : "E ";
longitude = (longitude < 0) ? -longitude : longitude;
int32_t longitude = abs(last_state.gps_data.longitude);
uint8_t longitude_int = longitude / 1000000;
int32_t longitude_dec = longitude % 1000000;
char *direction_lon = (last_state.gps_data.longitude < 0) ? "W " : "E ";
gfx_print(layout.line2_pos, layout.top_font, TEXT_ALIGN_CENTER,
color_white, direction);
color_white, direction_lon);
gfx_print(layout.line2_pos, layout.top_font, TEXT_ALIGN_RIGHT,
color_white, "%8.6f", longitude);
color_white, "%d.%.6d", longitude_int, longitude_dec);
gfx_print(layout.bottom_pos, layout.bottom_font, TEXT_ALIGN_CENTER,
color_white, "S %4.1fkm/h A %4.1fm",
color_white, "S %dkm/h A %dm",
last_state.gps_data.speed,
last_state.gps_data.altitude);
}

Wyświetl plik

@ -765,7 +765,7 @@ void ui_updateFSM(bool *sync_rtx)
_ui_changeWiper(&mod17CalData.tx_wiper, -1);
break;
case D_RXWIPER:
_ui_changeWiper(&mod17CalData.tx_wiper, -1);
_ui_changeWiper(&mod17CalData.rx_wiper, -1);
break;
case D_TXINVERT:
mod17CalData.bb_tx_invert -= 1;

Wyświetl plik

@ -0,0 +1,35 @@
#include <stdio.h>
#include <stdlib.h>
#include <gps.h>
static void assert_conversion(struct minmea_float *f, int32_t expected)
{
int32_t result = minmea_tofixedpoint(f);
if (result != expected)
{
printf("FAILED! result value %d - expected %d\n",
result, expected);
exit(1);
}
}
int main() {
printf("minmea coordinate conversion test\n");
struct minmea_float test = {5333735, 1000};
assert_conversion(&test, 53562250);
test.scale = 1;
test.value = 0;
assert_conversion(&test, 0);
test.scale = 1000;
test.value = -5333735;
assert_conversion(&test, -53562250);
test.scale = 1000;
test.value = -330;
assert_conversion(&test, -5500);
test.scale = 1000;
test.value = -3296;
assert_conversion(&test, -54933);
printf("PASS\n");
return 0;
}