Advertisement
KSA_MissionCtrl

Orbital Track Calculation Test

May 19th, 2015
309
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // This is a proof-of-concept linear calculation of a single Lat/Lon point given an initial orbit and time
  2. // altitude is currently also calculated since it is a simple calculation that derives from Lat/Lon calculations
  3. <script>
  4.     // craft icon, currently hard-coded to a probe
  5.     var ship = L.icon({
  6.         iconUrl: 'button_vessel_probe.png',
  7.         iconSize: [16, 16],
  8.     });
  9.  
  10.     // create the map with some custom options
  11.     map = new L.KSP.Map('map', {
  12.         layers: [L.KSP.CelestialBody.KERBIN],
  13.         zoom: 1,
  14.         center: [0,0],
  15.         bodyControl: false,
  16.         layersControl: false,
  17.         scaleControl: true,
  18.     });
  19.  
  20.     // let the user see the position of the cursor
  21.     // leaflet.js was modified to remove the biome, slope and elevation data displays
  22.     map.addControl(new L.KSP.Control.Info());
  23.  
  24.     // initial orbital data
  25.     // degrees converted to radians - (angle / 180) * Math.PI
  26.     var gmu = 3531.6;
  27.     var sma = 1200.06110157543;
  28.     var ecc = 0.00019551857301358601;
  29.     var inc = 45.023889091763799 * .017453292519943295;
  30.     var raan = 319.31870314879399 * .017453292519943295;
  31.     var arg = 179.83990894581601 * .017453292519943295;
  32.     var mean = 142.3534 * .017453292519943295;
  33.     var eph = 38419302.517532699;
  34.     var period = 4395.408;
  35.     var UT = 39330000.0;
  36.    
  37.     //////////////////////
  38.     // computeMeanMotion() <-- refers to function in KSPTOT code was expanded/extracted out of
  39.     //////////////////////
  40.    
  41.     // movement since the eph of the initial orbit
  42.     mean = mean +   Math.sqrt(gmu/Math.abs(sma)^3) * (UT - eph);
  43.    
  44.     ////////////////
  45.     // solveKepler()
  46.     ////////////////
  47.    
  48.     var EccA = -1;
  49.     if (mean < 0 || mean > 2*Math.PI) {
  50.         // expanded AngleZero2Pi() function
  51.         // abs(mod(real(Angle),2*pi));
  52.         // javascript has a modulo operator, not a function
  53.         mean = Math.abs(mean % (2*Math.PI));
  54.     }
  55.    
  56.     if (Math.abs(mean - 0) < 1E-8) {
  57.         EccA = 0;
  58.     } else if (Math.abs(mean - Math.PI) < 1E-8 ) {
  59.         EccA = Math.PI;
  60.     }  
  61.    
  62.     /////////////
  63.     // keplerEq()
  64.     /////////////
  65.    
  66.     // since there is no function return to break ahead of this statement, test if variable was modified
  67.     if (EccA = -1) {
  68.         var En  = mean;
  69.         var Ens = En - (En-ecc*Math.sin(En)- mean)/(1 - ecc*Math.cos(En));
  70.         while ( Math.abs(Ens-En) > 1E-10 ) {
  71.             En = Ens;
  72.             Ens = En - (En - ecc*Math.sin(En) - mean)/(1 - ecc*Math.cos(En));
  73.         }
  74.         EccA = Ens;
  75.     }
  76.    
  77.     ///////////////////////////////
  78.     // computeTrueAnomFromEccAnom()
  79.     ///////////////////////////////
  80.    
  81.     var upper = Math.sqrt(1+ecc) * Math.tan(EccA/2);
  82.     var lower = Math.sqrt(1-ecc);
  83.    
  84.     // expanded AngleZero2Pi() function
  85.     // abs(mod(real(Angle),2*pi));
  86.     // javascript has a modulo operator, not a function
  87.     var tru = Math.abs((Math.atan2(upper, lower) * 2) % (2*Math.PI));
  88.  
  89.     ///////////////////////////
  90.     // getStatefromKepler_Alg()
  91.     ///////////////////////////
  92.  
  93.     // Special Case: Circular Equitorial
  94.     if(ecc < 1E-10 && (inc < 1E-10 || Math.abs(inc-Math.PI) < 1E-10)) {
  95.         var l = raan + arg + tru;
  96.         tru = l;
  97.         raan = 0;
  98.         arg = 0;
  99.     }
  100.  
  101.     // Special Case: Circular Inclined
  102.     if(ecc < 1E-10 && inc >= 1E-10 && Math.abs(inc-Math.PI) >= 1E-10) {
  103.         var u = arg + tru;
  104.         tru = u;
  105.         arg = 0.0;
  106.     }
  107.  
  108.     // Special Case: Elliptical Equitorial
  109.     if(ecc >= 1E-10 && (inc < 1E-10 || Math.abs(inc-Math.PI) < 1E-10)) {
  110.         raan = 0;
  111.     }
  112.  
  113.     // vectors and matrices use the Slyvester library
  114.     var p = sma*(1-ecc^2);
  115.     var rPQW = $V([p*Math.cos(tru) / (1 + ecc*Math.cos(tru)),
  116.                                  p*Math.sin(tru) / (1 + ecc*Math.cos(tru)),
  117.                                  0]);
  118.  
  119.     var vPQW = $V([-Math.sqrt(gmu/p)*Math.sin(tru),
  120.                                  Math.sqrt(gmu/p)*(ecc + Math.cos(tru)),
  121.                                  0]);
  122.  
  123.     var TraansMatrix = $M([
  124.         [Math.cos(raan)*Math.cos(arg)-Math.sin(raan)*Math.sin(arg)*Math.cos(inc), -Math.cos(raan)*Math.sin(arg)-Math.sin(raan)*Math.cos(arg)*Math.cos(inc), Math.sin(raan)*Math.sin(inc)],
  125.         [Math.sin(raan)*Math.cos(arg)+Math.cos(raan)*Math.sin(arg)*Math.cos(inc), -Math.sin(raan)*Math.sin(arg)+Math.cos(raan)*Math.cos(arg)*Math.cos(inc), -Math.cos(raan)*Math.sin(inc)],
  126.         [Math.sin(arg)*Math.sin(inc), Math.cos(arg)*Math.sin(inc), Math.cos(inc)]
  127.     ]);
  128.  
  129.     var rVect = TraansMatrix.multiply(rPQW);
  130.     var vVect = TraansMatrix.multiply(vPQW);   
  131.  
  132.     /////////////////////
  133.     // getBodySpinAngle()
  134.     /////////////////////
  135.  
  136.     // hard-coded data for Kerbin
  137.     var bodySpinRate = 2*Math.PI/21599.912014540;
  138.  
  139.     // converted to radians
  140.     var rotInit = 90 * .017453292519943295;
  141.  
  142.     // expanded AngleZero2Pi() function
  143.     // abs(mod(real(Angle),2*pi));
  144.     // javascript has a modulo operator, not a function
  145.     var angle = rotInit + bodySpinRate*UT;
  146.     var spinAngle = Math.abs(angle % (2*Math.PI));
  147.  
  148.     //////////////////////////////////////
  149.     // getFixedFrameVectFromInertialVect()
  150.     //////////////////////////////////////
  151.  
  152.     var R = $M([
  153.         [Math.cos(spinAngle), -Math.sin(spinAngle), 0],
  154.         [Math.sin(spinAngle), Math.cos(spinAngle), 0],
  155.         [0, 0, 1]
  156.     ]);
  157.        
  158.     R = R.transpose();
  159.     var rVectECEF = R.multiply(rVect);
  160.  
  161.     //////////////////////////////////
  162.     // getLatLongAltFromInertialVect()
  163.     //////////////////////////////////
  164.  
  165.     // 2-norm or Euclidean norm of vector
  166.     var rNormECEF = Math.sqrt(rVectECEF.e(1) * rVectECEF.e(1) + rVectECEF.e(2) * rVectECEF.e(2) + rVectECEF.e(3) * rVectECEF.e(3));
  167.     var rNormECI = Math.sqrt(rVect.e(1) * rVect.e(1) + rVect.e(2) * rVect.e(2) + rVect.e(3) * rVect.e(3));
  168.    
  169.     // convert to degrees from radians - angle / Math.PI * 180
  170.     var lon = (Math.abs((Math.atan2(rVectECEF.e(2),rVectECEF.e(1))) % (2*Math.PI))) * 57.29577951308232;
  171.     var lat = (Math.PI/2 - Math.acos(rVectECEF.e(3)/rNormECEF)) * 57.29577951308232;
  172.     var alt = rNormECEF - 600;
  173.  
  174.     window.alert("UT: " + UT + "\ntru: " + tru * 57.29577951308232 + "\nlat: " + lat + "\nlon: " + lon + "\nalt: " + alt + "\nrNormECI: " + rNormECI + "\nrNormECEF: " + rNormECEF);
  175.    
  176.     // place the marker at the current Lat/Lon position for this UT
  177.     L.marker([lat, lon], {icon: ship, clickable: false}).addTo(map);
  178. </script>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement