1

I have some code, running on the PC as just java code, it gives the answer I want (the right one). On android the same code gives very different answers.

The code I am using was originally from the JsatTrack project, and gives these answers jun as a java project in eclipse (correct answers):

Lat [deg]:10.386382587628313
Lon [deg]:-93.88496253189982
Alt [m]  :418288.8335920386

The same code, with same input on Android gives this result:

Lat [deg]:-37.97635062163793
Lon [deg]:-147.34940989563563
Alt [m]  :6.86973250782099E29

I am new to java so where would I start looking to track down a problem like this. Would it be in the way android handles math for example?

So I guess my question boils down to why would the PC and android give different answers to the same maths questions? 2+2 should give t he same answer on any platform. The math in the SGP4 models is more complex but it's still just math.

The code is available here if any one wants to have a look

https://dl.dropbox.com/u/70291490/jstest.zip

Engineero
  • 12,340
  • 5
  • 53
  • 75
Rob
  • 2,511
  • 2
  • 20
  • 31
  • 2
    Please paste the part of your code that gives the bad result into your question... – ppeterka Jan 11 '13 at 10:48
  • Agree with you,@ppeterka, How can we find which class and code gives wrong result? – MysticMagicϡ Jan 11 '13 at 10:50
  • 2
    By the way, are you sure that the PC code gives the right answer? The Altitude data seems to be way off... Unless you are on [Low Earth Orbit](http://en.wikipedia.org/wiki/Geocentric_orbit#Altitude_classifications)... How do you obtain the GPS data on the PC? – ppeterka Jan 11 '13 at 10:52
  • @ppeterka it's not GPS data, but position of the iss in orbit, based on TLE info from nasa etc. Yes, the code when run on the pc gives correct answers as checked by other sources (http://www.isstracker.com/) and altitude is good at about 400km. I pasted a link as there are 14 or so classes, testSGP4 is the main code to run. – Rob Jan 11 '13 at 11:10
  • LOL, and I thought I spotted the obvious error :) Also, at the same time, please isolate a small part of the code that gives the output, and post it here - some of us might not be able to download from content sharing sites, and that prevents us to help you... – ppeterka Jan 11 '13 at 11:13
  • Thats the problem I guess, it's not a small bit of code, but hundreds and hundreds of lines like this. dZ = e2*Z; for(;;) { ZdZ = Z + dZ; Nh = Math.sqrt( rho2 + ZdZ*ZdZ ); SinPhi = ZdZ / Nh; // Sine of geodetic latitude N = R_equ / Math.sqrt(1.0-e2*SinPhi*SinPhi); dZ_new = N*e2*SinPhi; if ( Math.abs(dZ-dZ_new) < epsRequ ) break; dZ = dZ_new; } – Rob Jan 11 '13 at 11:24

2 Answers2

4

I am new to java so where would I start looking to track down a problem like this?

Connect your Android phone via USB on the PC and on Eclipse double click the left-hand side of the relative code that starts doing the math, it should appear a blue dot (code breakpoint). Click the button with a little bug on it (DEBUG button) on Eclipse toolbar. It will launch the project on the device and stop processing wherever u put the dot.

Now you can use the debug view toolbar to go through the code line-by-line and hoover the mouse on your classes/fields to see their values. You can do the same on the PC and compare each other value.

Budius
  • 39,391
  • 16
  • 102
  • 144
  • +1 .And extra care with floating point calculations. `strictfp` – S.D. Jan 11 '13 at 11:10
  • if they are not properly casted/used they can round values generating errors. – Budius Jan 11 '13 at 11:16
  • @Budius, thanks for the answer, but I didn't really phrase the question properly I think. What I meant was why whould code that is identical even give a different answer. I would not expect the PC to say 2+2=4 and android to say 2+2=0.34 – Rob Jan 11 '13 at 11:17
  • @Rob [Explained here](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – S.D. Jan 11 '13 at 11:17
  • Afaik, FP-Calculations may lead to different results depending on the system, a portability issue if you will. – Scorpio Jan 11 '13 at 11:18
0

The problem was very similar to my previous question on stackoverflow (http://stackoverflow.com/questions/14190692/how-to-debug-dalvikvm-rejecting-opcode)

Android can't handle lots of local variables, so defining them outside of the method is the solution. In my previous question dalvikvm was rejecting the method. In this case it was different, this code here:

ss = 78.0 / radiusearthkm + 1.0;

was setting ss as 1.0 as while radiuseathkm was being set a few lines earlier in the debugger it has a value of 0.0 when it should be 6378.135 so ss would = 1.0122292801892716. That error then propagates through the next few hundred calculations and there is the problem.

So I changed this:

public static boolean sgp4init(
        Gravconsttype whichconst, char opsmode, final int satn, final double epoch,
        final double xbstar, final double xecco, final double xargpo,
        final double xinclo, final double xmo, final double xno,
        final double xnodeo, SGP4SatData satrec)
{
    /* --------------------- local variables ------------------------ */
    double ao, ainv, con42, cosio, sinio, cosio2, eccsq,
            omeosq, posq, rp, rteosq,
            cnodm, snodm, cosim, sinim, cosomm, sinomm, cc1sq,
            cc2, cc3, coef, coef1, cosio4, day, dndt,
            em, emsq, eeta, etasq, gam, argpm, nodem,
            inclm, mm, nm, perige, pinvsq, psisq, qzms24,
            rtemsq, s1, s2, s3, s4, s5, s6,
            s7, sfour, ss1, ss2, ss3, ss4, ss5,
            ss6, ss7, sz1, sz2, sz3, sz11, sz12,
            sz13, sz21, sz22, sz23, sz31, sz32, sz33,
            tc, temp, temp1, temp2, temp3, tsi, xpidot,
            xhdot1, z1, z2, z3, z11, z12, z13,
            z21, z22, z23, z31, z32, z33,
            qzms2t, ss, j2, j3oj2, j4, x2o3, //r[3], v[3],
            tumin, mu, radiusearthkm, xke, j3;
    double[] r = new double[3];
    double[] v = new double[3];

to this:

static double radiusearthkm, ao, ainv, con42, cosio, sinio, cosio2, eccsq,
        omeosq, posq, rp, rteosq,
        cnodm, snodm, cosim, sinim, cosomm, sinomm, cc1sq,
        cc2, cc3, coef, coef1, cosio4, day, dndt,
        em, emsq, eeta, etasq, gam, argpm, nodem,
        inclm, mm, nm, perige, pinvsq, psisq, qzms24,
        rtemsq, s1, s2, s3, s4, s5, s6,
        s7, sfour, ss1, ss2, ss3, ss4, ss5,
        ss6, ss7, sz1, sz2, sz3, sz11, sz12,
        sz13, sz21, sz22, sz23, sz31, sz32, sz33,
        tc, temp, temp1, temp2, temp3, tsi, xpidot,
        xhdot1, z1, z2, z3, z11, z12, z13,
        z21, z22, z23, z31, z32, z33,
        qzms2t, ss, j2, j3oj2, j4, x2o3, //r[3], v[3],
        tumin, mu,  xke, j3;


public static boolean sgp4init(
        SGP4unit_a.Gravconsttype whichconst, char opsmode, final int satn, final double epoch,
        final double xbstar, final double xecco, final double xargpo,
        final double xinclo, final double xmo, final double xno,
        final double xnodeo, SGP4SatData satrec)
{

    double[] r = new double[3];
    double[] v = new double[3];

and all is now working correctly.

Rob
  • 2,511
  • 2
  • 20
  • 31