hopperpop / sgp4-library Goto Github PK
View Code? Open in Web Editor NEWLibrary for calculating satellites positions and predicting overpasses.
License: MIT License
Library for calculating satellites positions and predicting overpasses.
License: MIT License
Seems like the result of invjday and findsat is off.
Compared to N2YO and gPredict, the nearest passes are off by 1-5 minutes, the current calculated direction of the satellite seems to be off, sometimes even by as much as 30 degrees elevation.
Is this a limitation of a simplified SGP4 or am I just being an idiot?
Hi,
Thank you for this library. I'm planning to use it for my upcoming project related to the ISS.
I was wondering why did you comment all the code related to rates and velocity?
Have you had trouble to make it work on ESP? Or maybe it is due to performance considerations?
Do you think I can safely uncomment those lines to get the rates back?
Thank you
Receive “‘int min’ redeclared as a different type of symbol” error when compiling the SGP4 predictor example using either Arduino IDE or Web editor.
i,
Many thanks for this great library.
I did compile on ESP32 but crashes withthis error code at run : "stack smashing protect failure"
After investigation i found that the problem was into sgp4io.cpp when extracting float from the TLE for instance on this line:
memcpy( tempstr, &longstr1[20] , 12); tempstr[12] = '\0'; satrec.epochdays = atof(tempstr);
To solve the issue I have used String() arduino function.
satrec.epochdays = str1.substring(20, 32).toDouble();
sgp4io.cpp
companion code for
fundamentals of astrodynamics and applications
2007
by david vallado
(w) 719-573-2600, email [email protected]
27 Aug 10 david vallado
fix input format and delete unused variables in twoline2rv
3 sep 08 david vallado
add operationmode for afspc (a) or improved (i)
9 may 07 david vallado
fix year correction to 57
27 mar 07 david vallado
misc fixes to manual inputs
14 aug 06 david vallado
original baseline
---------------------------------------------------------------- */
#include "sgp4io.h"
#include "stdlib.h"
/* -----------------------------------------------------------------------------
*
function twoline2rv
manual 'm'
void twoline2rv
(
char longstr1[130], char longstr2[130],
char opsmode, gravconsttype whichconst,
elsetrec& satrec
)
{
char tempstr[12];
const double deg2rad = pi / 180.0; // 0.0174532925199433
const double xpdotp = 1440.0 / (2.0 *pi); // 229.1831180523293
double sec, mu, radiusearthkm, tumin, xke, j2, j3, j4, j3oj2;
double startsec, stopsec, startdayofyr, stopdayofyr, jdstart, jdstop;
int startyear, stopyear, startmon, stopmon, startday, stopday,
starthr, stophr, startmin, stopmin;
int cardnumb, numb, j;
long revnum = 0, elnum = 0;
char classification, intldesg[11];
int year = 0;
int mon, day, hr, minute, nexp, ibexp;
getgravconst( whichconst, tumin, mu, radiusearthkm, xke, j2, j3, j4, j3oj2 );
satrec.error = 0;
// set the implied decimal points since doing a formated read
// fixes for bad input data values (missing, ...)
for (j = 10; j <= 15; j++)
if (longstr1[j] == ' ')
longstr1[j] = '_';
if (longstr1[44] != ' ')
longstr1[43] = longstr1[44];
longstr1[44] = '.';
if (longstr1[7] == ' ')
longstr1[7] = 'U';
if (longstr1[9] == ' ')
longstr1[9] = '.';
for (j = 45; j <= 49; j++)
if (longstr1[j] == ' ')
longstr1[j] = '0';
if (longstr1[51] == ' ')
longstr1[51] = '0';
if (longstr1[53] != ' ')
longstr1[52] = longstr1[53];
longstr1[53] = '.';
longstr2[25] = '.';
for (j = 26; j <= 32; j++)
if (longstr2[j] == ' ')
longstr2[j] = '0';
if (longstr1[62] == ' ')
longstr1[62] = '0';
if (longstr1[68] == ' ')
longstr1[68] = '0';
/**
sscanf(longstr1,"%2d %5ld %1c %10s %2d %12lf %11lf %7lf %2d %7lf %2d %2d %6ld ",
&cardnumb,&satrec.satnum,&classification, intldesg, &satrec.epochyr,
&satrec.epochdays,&satrec.ndot, &satrec.nddot, &nexp, &satrec.bstar,
&ibexp, &numb, &elnum );
**/
String str1= String(longstr1);
satrec.satnum = str1.substring(2, 7).toInt();
satrec.epochyr = str1.substring(18, 20).toInt();
satrec.epochdays = str1.substring(20, 32).toDouble();
satrec.ndot = str1.substring(32, 43).toDouble();
satrec.nddot = str1.substring(43, 50).toDouble();
nexp = str1.substring(50, 52).toInt();
satrec.bstar = str1.substring(52, 59).toDouble();
ibexp = str1.substring(59, 61).toInt();
//memcpy( tempstr, &longstr1[0] , 2); tempstr[1] = '\0'; satrec.cardnumb = atoi(tempstr);
//memcpy( tempstr, &longstr1[2] , 5); tempstr[5] = '\0'; satrec.satnum = atol(tempstr); //
//classification = longstr1[7];
//memcpy( intldesg, &longstr1[8] , 10); intldesg[10] = '\0';
//memcpy( tempstr, &longstr1[18] , 2); tempstr[2] = '\0'; satrec.epochyr = atoi(tempstr); //
// memcpy( tempstr, &longstr1[20] , 12); tempstr[12] = '\0'; satrec.epochdays = atof(tempstr);//
//memcpy( tempstr, &longstr1[32] , 11); tempstr[11] = '\0'; satrec.ndot = atof(tempstr);
//memcpy( tempstr, &longstr1[43] , 7); tempstr[7] = '\0'; satrec.nddot = atof(tempstr);//
//memcpy( tempstr, &longstr1[50] , 2); tempstr[2] = '\0'; nexp = atoi(tempstr); //
//memcpy( tempstr, &longstr1[52] , 7); tempstr[7] = '\0'; satrec.bstar = atof(tempstr);//
//memcpy( tempstr, &longstr1[59] , 2); tempstr[2] = '\0'; ibexp = atoi(tempstr);//
//memcpy( tempstr, &longstr1[61] , 2); tempstr[2] = '\0'; numb = atoi(tempstr);
//memcpy( tempstr, &longstr1[63] , 6); tempstr[6] = '\0'; elnum = atol(tempstr);
String str2= String(longstr2);
satrec.satnum = str2.substring(2, 7).toInt();
satrec.inclo = str2.substring(7, 16).toDouble();
satrec.nodeo = str2.substring(16, 25).toDouble();
satrec.ecco = str2.substring(25, 33).toDouble();
satrec.argpo = str2.substring(33, 42).toDouble();
satrec.mo = str2.substring(42, 51).toDouble();
satrec.no = str2.substring(51, 62).toDouble();
// memcpy( tempstr, &longstr2[2] , 5); tempstr[5] = '\0'; satrec.satnum = atol(tempstr);//
//memcpy( tempstr, &longstr2[7] , 9); tempstr[9] = '\0'; satrec.inclo = atof(tempstr);/
//memcpy( tempstr, &longstr2[16] , 9); tempstr[9] = '\0'; satrec.nodeo = atof(tempstr);//
//memcpy( tempstr, &longstr2[25] , 8); tempstr[8] = '\0'; satrec.ecco = atof(tempstr);//
//memcpy( tempstr, &longstr2[33] , 9); tempstr[9] = '\0'; satrec.argpo = atof(tempstr);//
//memcpy( tempstr, &longstr2[42] , 9); tempstr[9] = '\0'; satrec.mo = atof(tempstr);//
//memcpy( tempstr, &longstr2[51] , 11); tempstr[10] = '\0'; satrec.no = atof(tempstr);//
//memcpy( tempstr, &longstr2[63] , 6); tempstr[6] = '\0'; revnum = atol(tempstr);
// ---- find no, ndot, nddot ----
satrec.no = satrec.no / xpdotp; //* rad/min
satrec.nddot= satrec.nddot * pow(10.0, nexp);
satrec.bstar= satrec.bstar * pow(10.0, ibexp);
// ---- convert to sgp4 units ----
satrec.a = pow( satrec.no*tumin , (-2.0/3.0) );
satrec.ndot = satrec.ndot / (xpdotp*1440.0); //* ? * minperday
satrec.nddot= satrec.nddot / (xpdotp*1440.0*1440);
// ---- find standard orbital elements ----
satrec.inclo = satrec.inclo * deg2rad;
satrec.nodeo = satrec.nodeo * deg2rad;
satrec.argpo = satrec.argpo * deg2rad;
satrec.mo = satrec.mo * deg2rad;
satrec.alta = satrec.a*(1.0 + satrec.ecco) - 1.0;
satrec.altp = satrec.a*(1.0 - satrec.ecco) - 1.0;
// ----------------------------------------------------------------
// find sgp4epoch time of element set
// remember that sgp4 uses units of days from 0 jan 1950 (sgp4epoch)
// and minutes from the epoch (time)
// ----------------------------------------------------------------
// ---------------- temp fix for years from 1957-2056 -------------------
// --------- correct fix will occur when year is 4-digit in tle ---------
if (satrec.epochyr < 57)
year= satrec.epochyr + 2000;
else
year= satrec.epochyr + 1900;
days2mdhms ( year,satrec.epochdays, mon,day,hr,minute,sec );
jday( year,mon,day,hr,minute,sec, 0,false,satrec.jdsatepoch );
/***
// ---- input start stop times manually
if ((typerun != 'v') && (typerun != 'c'))
{
// ------------- enter start/stop ymd hms values --------------------
if (typeinput == 'e')
{
printf("input start prop year mon day hr min sec \n");
// make sure there is no space at the end of the format specifiers in scanf!
scanf( "%i %i %i %i %i %lf",&startyear, &startmon, &startday, &starthr, &startmin, &startsec);
fflush(stdin);
jday( startyear,startmon,startday,starthr,startmin,startsec, jdstart );
printf("input stop prop year mon day hr min sec \n");
scanf( "%i %i %i %i %i %lf",&stopyear, &stopmon, &stopday, &stophr, &stopmin, &stopsec);
fflush(stdin);
jday( stopyear,stopmon,stopday,stophr,stopmin,stopsec, jdstop );
startmfe = (jdstart - satrec.jdsatepoch) * 1440.0;
stopmfe = (jdstop - satrec.jdsatepoch) * 1440.0;
printf("input time step in minutes \n");
scanf( "%lf",&deltamin );
}
// -------- enter start/stop year and days of year values -----------
if (typeinput == 'd')
{
printf("input start year dayofyr \n");
scanf( "%i %lf",&startyear, &startdayofyr );
printf("input stop year dayofyr \n");
scanf( "%i %lf",&stopyear, &stopdayofyr );
days2mdhms ( startyear,startdayofyr, mon,day,hr,minute,sec );
jday( startyear,mon,day,hr,minute,sec, jdstart );
days2mdhms ( stopyear,stopdayofyr, mon,day,hr,minute,sec );
jday( stopyear,mon,day,hr,minute,sec, jdstop );
startmfe = (jdstart - satrec.jdsatepoch) * 1440.0;
stopmfe = (jdstop - satrec.jdsatepoch) * 1440.0;
printf("input time step in minutes \n");
scanf( "%lf",&deltamin );
}
// ------------------ enter start/stop mfe values -------------------
if (typeinput == 'm')
{
printf("input start min from epoch \n");
scanf( "%lf",&startmfe );
printf("input stop min from epoch \n");
scanf( "%lf",&stopmfe );
printf("input time step in minutes \n");
scanf( "%lf",&deltamin );
}
}
***/
// ---------------- initialize the orbit at sgp4epoch -------------------
sgp4init( whichconst, opsmode, satrec.satnum, satrec.jdsatepoch-2433281.5, satrec.bstar,
satrec.ecco, satrec.argpo, satrec.inclo, satrec.mo, satrec.no,
satrec.nodeo, satrec);
} // end twoline2rv
/* -----------------------------------------------------------------------------
*
function twolineChecksum
unsigned int cks = 0;
const char* checksumpointer = longstr + 68;
for (const char* p = longstr; p < checksumpointer; p++){
switch(*p){
case 0:
return false;
break;
case '-':
cks++;
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
cks += *p - '0';
break;
}
}
cks %= 10; //modulo 10
if (cks + '0' == *checksumpointer)
return true;
return false;
}
`
This mod now works with ESP32 arduino and should work as well with ESP8266
Once again thank you for this lib
JP
Hello @Hopperpop ,
Thank you again for sharing this library. It is a really nice piece of work!
Could you please add this library to the Arduino Library Manager - so it can be installed automatically through the Arduino IDE?
You can find full instructions on how to add a library to the registry here:
https://github.com/arduino/library-registry
(Please do include PR #5 and up-issue the library tag first. Thank you!)
Sincere thanks,
Paul
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.