Changed Grid Square calculations.

Changed Grid Square  calculations from double to float that has adequate precision.
pull/16/merge
Bob Larkin 1 year ago
parent 2e7df3af34
commit 78b7fc91dc
  1. 4
      examples/FT8Receive/FT8Receive.ino
  2. 6
      examples/FT8Receive/decode_ft8R.ino
  3. 70
      examples/FT8Receive/locatorR.ino
  4. 69
      examples/FT8Receive/maidenheadR.ino
  5. 6
      radioFT8Demodulator_F32.h

@ -63,6 +63,10 @@
#define ft8_min_freq FT8_FREQ_SPACING * LOW_FREQ_INDEX
#define ft8_msg_samples 92
// A couple of prototypes to help the compile order
void init_DSP(void);
void extract_power(int);
// Alternate interface format.
// #define W5BAA

@ -44,7 +44,7 @@ const int kMax_decoded_messages = 20;
const int kMax_message_length = 20;
const int kMin_score = 40; // Minimum sync score threshold for candidates
int validate_locator(char locator[]);
int strindex(char s[],char t[]);
int strindex(char s[], char t[]);
typedef struct
{
@ -220,8 +220,8 @@ int ft8_decode(void) {
strcpy(Target_Locator, new_decoded[num_decoded].field3);
if (validate_locator(Target_Locator) == 1)
{
distance = Target_Distance(Target_Locator);
new_decoded[num_decoded].distance = (int)distance;
distance = Target_Distancef(Target_Locator);
new_decoded[num_decoded].distance = (int)(0.5f + distance);
}
else
{

@ -1,24 +1,16 @@
/*
* locator.ino
*
* Was locator.ino
* Created on: Nov 4, 2019
* Author: user
*/
// locatorR.ino Bob Larkin 12 Nov 2022
// Built from the K. Goba double precision files.
// Data types float precision, funtion unchanged, names have added 'f'
//#include "locator.h"
//#include <math.h>
//#include "arm_math.h"
// TODO - Looks like single precision would be adequate - RSL
const double EARTH_RAD = 6371; //radius in km
//void process_locator(char locator[]);
//double distance(double lat1, double lon1, double lat2, double lon2);
//double deg2rad(double deg);
float Latitude, Longitude;
float Station_Latitude, Station_Longitude;
float Target_Latitude, Target_Longitude;
//float Target_Distance(char target[]);
const float32_t EARTH_RAD = 6371.0f; //radius in km
float32_t Latitude, Longitude;
float32_t Station_Latitude, Station_Longitude;
float32_t Target_Latitude, Target_Longitude;
void set_Station_Coordinates(char station[]){
process_locator(station);
@ -26,21 +18,21 @@ void set_Station_Coordinates(char station[]){
Station_Longitude = Longitude;
}
float Target_Distance(char target[]) {
float targetDistance;
float32_t Target_Distancef(char target[]) {
float32_t targetDistance;
process_locator(target);
Target_Latitude = Latitude;
Target_Longitude = Longitude;
targetDistance = (float) distance((double)Station_Latitude,(double)Station_Longitude,
(double)Target_Latitude,(double)Target_Longitude);
targetDistance = distancef((float32_t)Station_Latitude, (float32_t)Station_Longitude,
(float32_t)Target_Latitude, (float32_t)Target_Longitude);
return targetDistance;
}
void process_locator(char locator[]) {
uint8_t A1, A2, N1, N2;
uint8_t A1_value, A2_value, N1_value, N2_value;
float Latitude_1, Latitude_2, Latitude_3;
float Longitude_1, Longitude_2, Longitude_3;
float32_t Latitude_1, Latitude_2, Latitude_3;
float32_t Longitude_1, Longitude_2, Longitude_3;
A1 = locator[0];
A2 = locator[1];
N1 = locator[2];
@ -49,27 +41,29 @@ void process_locator(char locator[]) {
A2_value = A2-65;
N1_value = N1- 48;
N2_value = N2 - 48;
Latitude_1 = (float) A2_value * 10;
Latitude_2 = (float) N2_value;
Latitude_3 = (11.0/24.0 + 1.0/48.0) - 90.0;
Latitude_1 = (float32_t) A2_value * 10.0f;
Latitude_2 = (float32_t) N2_value;
Latitude_3 = (11.0f/24.0f + 1.0f/48.0f) - 90.0f;
Latitude = Latitude_1 + Latitude_2 + Latitude_3;
Longitude_1 = (float)A1_value * 20.0;
Longitude_2 = (float)N1_value * 2.0;
Longitude_3 = 11.0/12.0 + 1.0/24.0;
Longitude = Longitude_1 + Longitude_2 + Longitude_3 - 180.0;
Longitude_1 = (float32_t)A1_value * 20.0f;
Longitude_2 = (float32_t)N1_value * 2.0f;
Longitude_3 = 11.0f/12.0f + 1.0f/24.0f;
// global Longitude
Longitude = Longitude_1 + Longitude_2 + Longitude_3 - 180.0f;
}
// distance (km) on earth's surface from point 1 to point 2
double distance(double lat1, double lon1, double lat2, double lon2) {
double lat1r = deg2rad(lat1);
double lon1r = deg2rad(lon1);
double lat2r = deg2rad(lat2);
double lon2r = deg2rad(lon2);
return acos(sin(lat1r) * sin(lat2r)+cos(lat1r) * cos(lat2r) * cos(lon2r-lon1r)) * EARTH_RAD;
float32_t distancef(float32_t lat1, float32_t lon1, float32_t lat2, float32_t lon2) {
float32_t lat1r = deg2radf(lat1);
float32_t lon1r = deg2radf(lon1);
float32_t lat2r = deg2radf(lat2);
float32_t lon2r = deg2radf(lon2);
return acos(sinf(lat1r) * sinf(lat2r) +
cosf(lat1r) * cosf(lat2r) * cosf(lon2r-lon1r)) * EARTH_RAD;
}
// convert degrees to radians
double deg2rad(double deg)
// convert degrees to radians (i.e., * PI/180)
float32_t deg2radf(float32_t deg)
{
return deg * (PI / 180.0);
return deg * 0.017453292f;
}

@ -1,36 +1,31 @@
//#include "maidenhead.h"
//#include <math.h>
//#include <stdio.h>
//#include <string.h>
//#ifdef __cplusplus
//extern "C" {
//#endif
// TODO This looks like a float change?? RSL
// maidenheadR.ino Bob Larkin 12 Nov 2022
// Built from the K. Goba double precision files.
// Data types float precision, funtion unchanged, names have added 'f'
char letterizeR(int x) {
return (char) x + 65;
}
char* get_mh(double lat, double lon, int size) {
// Input lat, lon in degrees; Input grid locator size 4, 6, 8, or 10
// Output grid square string pointer.
char* get_mhf(float32_t lat, float32_t lon, int size) {
static char locator[11];
double LON_F[]={20,2.0,0.083333,0.008333,0.0003472083333333333};
double LAT_F[]={10,1.0,0.0416665,0.004166,0.0001735833333333333};
float32_t LON_F[]={20.0f, 2.0f, 0.0833333f, 0.008333f, 0.00034720833f};
float32_t LAT_F[]={10.0f, 1.0f, 0.0416665f, 0.004166f, 0.00017358333f};
int i;
lon += 180;
lat += 90;
lon += 180.0f;
lat += 90.0f;
if (size <= 0 || size > 10) size = 6;
size/=2; size*=2;
for (i = 0; i < size/2; i++){
if (i % 2 == 1) {
locator[i*2] = (char) (lon/LON_F[i] + '0');
locator[i*2+1] = (char) (lat/LAT_F[i] + '0');
locator[i*2] = (char)(lon/LON_F[i] + '0');
locator[i*2+1] = (char)(lat/LAT_F[i] + '0');
} else {
locator[i*2] = letterizeR((int) (lon/LON_F[i]));
locator[i*2+1] = letterizeR((int) (lat/LAT_F[i]));
locator[i*2] = letterizeR((int)(lon/LON_F[i]));
locator[i*2+1] = letterizeR((int)(lat/LAT_F[i]));
}
lon = fmod(lon, LON_F[i]);
lat = fmod(lat, LAT_F[i]);
@ -47,32 +42,30 @@ char* complete_mh(char* locator) {
return locator2;
}
double mh2lon(char* locator) {
double field, square, subsquare, extsquare, precsquare;
// Convert grid square string to longitude
float32_t mh2lonf(char* locator) {
float32_t field, square, subsquare, extsquare, precsquare;
int len = strlen(locator);
if (len > 10) return 0;
if (len < 10) locator = complete_mh(locator);
field = (locator[0] - 'A') * 20.0;
square = (locator[2] - '0') * 2.0;
subsquare = (locator[4] - 'A') / 12.0;
extsquare = (locator[6] - '0') / 120.0;
precsquare = (locator[8] - 'A') / 2880.0;
return field + square + subsquare + extsquare + precsquare - 180;
field = (locator[0] - 'A') * 20.0f;
square = (locator[2] - '0') * 2.0f;
subsquare = (locator[4] - 'A') / 12.0f;
extsquare = (locator[6] - '0') / 120.0f;
precsquare = (locator[8] - 'A') / 2880.0f;
return field + square + subsquare + extsquare + precsquare - 180.0f;
}
double mh2lat(char* locator) {
double field, square, subsquare, extsquare, precsquare;
// Convert grid square string to latitude
float32_t mh2latf(char* locator) {
float field, square, subsquare, extsquare, precsquare;
int len = strlen(locator);
if (len > 10) return 0;
if (len < 10) locator = complete_mh(locator);
field = (locator[1] - 'A') * 10.0;
square = (locator[3] - '0') * 1.0;
subsquare = (locator[5] - 'A') / 24.0;
extsquare = (locator[7] - '0') / 240.0;
precsquare = (locator[9] - 'A') / 5760.0;
field = (locator[1] - 'A') * 10.0f;
square = (locator[3] - '0') * 1.0f;
subsquare = (locator[5] - 'A') / 24.0f;
extsquare = (locator[7] - '0') / 240.0f;
precsquare = (locator[9] - 'A') / 5760.0f;
return field + square + subsquare + extsquare + precsquare - 90;
}
//#ifdef __cplusplus
//}
//#endif

@ -115,7 +115,7 @@ public:
void initialize(void) {
// Initialize 2 FIR instances (ARM DSP Math Library)
//arm_fir_init_f32 (arm_fir_instance_f32 *S, uint16_t numTaps,
const float32_t *pCoeffs, float32_t *pState, uint32_t blockSize)
// const float32_t *pCoeffs, float32_t *pState, uint32_t blockSize)
arm_fir_init_f32(&fir_inst1, 55, &firDecimate1[0], &dec1FIRWork[0], 128UL);
arm_fir_init_f32(&fir_inst2, 167, &firDecimate2[0], &dec2FIRWork[0], 128UL);
// CHECK SAMPLE RATE AND SET index <<<<<<<<<<<<<
@ -350,7 +350,7 @@ int32_t kkk;
* Sampling frequency = 96000 Hz
* 0 Hz - 3200 Hz ripple = 0.065 dB
* 9600 Hz - 48000 Hz att = -81.1 dB */
const float32_t firDecimate1[55] = { // constexpr static
float32_t firDecimate1[55] = { // constexpr static
0.000037640f, 0.000248621f, 0.000535682f, 0.001017563f, 0.001647298,
0.002359693f, 0.003009942f, 0.003388980f, 0.003245855f, 0.002335195,
0.000482309f, -0.002343975f, -0.005965316f, -0.009953093f, -0.013627779f,
@ -367,7 +367,7 @@ const float32_t firDecimate1[55] = { // constexpr static
* Sampling frequency = 19200 Hz
* 0 Hz - 2800 Hz ripple = 0.073 dB
* 3200 Hz - 9600 Hz att = -80.0 dB */
const float32_t firDecimate2[167] = {
float32_t firDecimate2[167] = {
0.000200074f, 0.000438821f, 0.000648425f, 0.000636175f, 0.000315069f,
-0.000193500f, -0.000591064f, -0.000600896f, -0.000202482f, 0.000301473f,
0.000486276f, 0.000152104f, -0.000466930f, -0.000846593f, -0.000601871f,

Loading…
Cancel
Save