• Content count

  • Joined

  • Last visited

Community Reputation

46 Excellent

1 Follower

About Pand5461

  • Rank
    Spacecraft Engineer
  1. @Jim DiGriz I clearly remember that even without state prediction, dVorbit/dt was not mu/R^2. The offset was exactly what's expected from the rotating coordinate axes. I'm trying to rewrite PEG for maneuver execution now. Instead of burning the specified deltaV, it takes the trajectory after node as the reference and tries to put the ship onto it. The unbound orbital element in this case is the anomaly, i.e. where on that trajectory ship completes the burn. Compare with the unbound AoP for ascent, i.e. how the SMA is aligned relative to DN-AN line. So far the result does not seem as much improvement over burning specified dV vector, but the main goal is to test my implementation of the core functions. @Reddy can you explain your logic of control loop convergence? Do you iterate until both Vgo and tgo converged and then update the steering command? I saw in the russian source that new steering vector can be issued right after tgo has converged and Vgo convergence is the condition to start next loop. But that produces side effects when tgo "converges" to the total fuel burnout time. On the other hand, setting convergence time threshold as absolute value (say, 0.1s) leads to too many iterations initially, while the actual steering direction does not change much between them. On the fun side: tried to understand why my numerical integration-based CSE is off by a few km on 30-second timescale. Realized I just skipped the last integration step.
  2. IDK if that's cheating or not but: you can read SMAs from the configs in planetpack folder. For OPM, it's GameData/OPM/KopernicusConfigs. There's a .cfg for each new celestial that contains its orbital elements in the "Orbit" field.
  3. That intended to be a joke meaning "unmanned space programs also deserve to be remembered". I apologize if it offended you. I just quietly assumed that people on this forums usually know that there were pre-Apollo unmanned Moon landings, so I don't need to explicitly say it.
  4. Why that protein chauvinism? Of course I am referring to Luna-9 and Syrveyors (that were never intended to impact the surface, btw).
  5. @ferram4 Hooray! Instead, it promptly installs it on 1.2.2 and crashes the game.
  6. Depends very much on where your initial periapsis is. If it's above the ground, no difference from the case when you go to parking orbit first. Ideal case: Pe is just above or just below the ground. If you manage to stop right there, that's the most fuel-efficient way to do a landing. Worst case: you're falling vertically on the Mun. To stop, you must constantly burn against the gravity vector. Probably, burning radial to move Pe at or above the ground level while you're still far away will be more efficient than braking at vertical descent. Everything else falls somewhere in between, impact trajectories being usually worse because thrust vector must be more aligned with gravity vector. In stock, there's no reason no to go for a parking orbit first because then you can choose where to land. IRL, first Moon landings were from an impact trajectory. My guess is that landing guidance was much simpler that way.
  7. @Spaced Out short answer is: of course there are some deviations but we know how to deal with them. Long answer: modern launchers have onboard guidance systems that detect the perturbations and recalculate the attitude program needed to get to desired orbit on the go (so-called closed-loop control). Switch to closed-loop control usually happens when rocket leaves the thick part of atmosphere, as @IncongruousGoat already mentioned. One reason for that is that onboard computers have very limited capabilities to properly optimize atmospheric flight. Another is that large perturbations of reference trajectory early in flight will likely result in mission failure anyways, and small ones can be easily adjusted for later. So it's just much more reasonable to calculate the reference atmospheric trajectory and follow that as close as possible. In the early space era, I believe, a number of trajectories were precomputed for missions where precision was crucial (like shooting the Moon), accounting for possible deviations. Rocket was then guided from ground stations based on which trajectory it's currently on. Sometimes the precision was just not that important, so just a simple precomputed pitch-time program for the whole ascent was enough.
  8. Ha! Looks like my "corrections" increased the rotation instead of compensating it. This is what happens when you adapt formulas written in right-handed inertial frame for left-handed rotating one. (Alleged violation of 2.2g) I'll just go brute-force and recompute coordinates like this: function chFrame { parameter Vec, oldIx, newIx. //changes vector from frame with ix = oldIx, iy = V(0,1,0) to frame with ix = newIx, iy = V(0,1,0) //this works under the assumption that all planetary axes are V(0,1,0) in KSP //Assumed that oldIx and newIx are Solar Prime Vectors at different moments of time local oldIz to V(-oldIx:z, 0, oldIx:x). local newIz to V(-newIx:z, 0, newIx:x). return vdot(Vec, oldIx)*newIx + vdot(Vec, oldIz)*newIz + Vec:y * V(0,1,0). }
  9. @Reddy looking at your video - I don't think rotating frame is really much of an issue, at least for RSS. Kerbin's rotation is 4 times faster, and the extra apparent acceleration due to rotating frame is 0.6 m/s2 at LKO, very much noticeable. As far as I understand it, below certain altitude KSP internally uses rotating frame with the good old centrifugal and Coriolis forces. In that frame, cartesian coordinates of launch site (or any fixed geoposition) remain fixed for any observer resting on ground. All constant vectors in inertial frame (of which I only know the Solar Prime vector), on the contrary, appear rotating. Now here's the trick: orbital velocity components exposed in kOS are the velocity in inertial frame projected onto instantaneous position of rotating axes. This makes orbital velocity at low altitudes inconsistent with position changes ("inertial force"). At high altitudes, vorbit = dR/dt, at low vsurface = dR/dt. What is even more confusing is that at low altitudes it appears as though dvorbit / dt <> -body:mu*R / |R|3 on coasting trajectory. Again, this is because we can only compare this component-wise in kOS. And vx = (v, ix), so dvx / dt = (dv/dt, ix) + (v, dix / dt) = gx + (v, [Omega x ix ]), where gx = -body:mu*Rx / |R|3 is the projection of gravity vector onto X axis and Omega is rotational speed. Overall, we get dv' / dt = g + [ v' x Omega ] where v' is the set of coordinates for vorbit in the rotating frame. This appears as quite a drastic change if you log body:position and ship:velocity:orbit along orbit with Ap above critical altitude and Pe below it. Now, about consequences of this. Both current state (r, v) and desired state (rd, vd) change in the same way, yes, but they are rotating, not translating. That means that the difference between them is not constant but also rotates. To illustrate, let's assume you initialize r at launchpad with coordinates V(600, 0, 0) and at the end of loop you compute rd 100 km directly above it at V(700, 0, 0). Let's say a computation loop takes one second. In the inertial frame, you'd expect that V(600, 0, 0) does not point at launchpad anymore because the launchpad has rotated. However, V(600, 0, 0) still points exactly at launchpad in the rotating frame. Therefore, rd = V(700, 0, 0) in the new coordinate frame is again directly above KSC and not a bit westward as you probably want. The solution is to rotate all computed positions, velocities and directions a little bit every iteration.
  10. @Jim DiGriz, thing is, you need to correct all vectors computed in the old coordinate frame, not only velocity.
  11. Ugh, now how to extract this from kOS (I'm starting to suspect it's not necessarily 100 km)? The only way I can think of is to compare SolarPrimeVector between the iterations, like this: // On every PEG loop initialization wait 0. local dt to missiontime - peg_prev["t"]. local SPV to SolarPrimeVector. if peg_prev["SPr"] <> SPV { local omega to body:angularvel. local rot to { parameter vec. return vec - vcrs(omega, vec)*dt. }. set peg_now["Rbias"] to rot(peg_now["Rbias"]). //rotate everything else you need } set peg_prev["SPr"] to SPV. set peg_prev["t"] to peg_prev["t"] + dt. Jim, Thanks for the references, trying to dig into.
  12. Continuous burn to orbit, though possible, is suboptimal in stock. Either upper stages have reasonable TWR and need to pitch wildly, or upper stages have extremely low TWR inducing gravity losses. The real Soyuz launchers suffered this problem because they had somewhat overpowered upper stages that could not be reignited. We all know the solution - burn to a suborbital trajectory at full thrust, then circularize at full thrust. It is mathematically proven that if some maneuver can be done either by a single throttled burn or two separated burns at full thrust, the latter case is more optimal. And there are 5 elements constrained. Inclination and LAN are defined explicitly. Altitude, speed (scalar) and angle of velocity to local horizon are three parameters, so they define SMA (from total energy), eccentricity (from rotational momentum) and anomaly (from altitude, considering SMA and ECC are known). Erm... I was sure I saw the projection in your code. Actually, you didn't even need to go that far - just projecting current location on the target plane and scaling it accordingly works just as well. What I haven't seen is the account of rotating reference frame below 100 km. Again, this is more stock-related because of faster rotation and switch to inertial frame well above atmosphere (and above my typical parking orbit).
  13. @Reddy do you have an idea, by chance, how to deal with coasting phases? In the current form, 5 orbital elements out of 6 must be specified (except for argument of periapsis). While this is good in RSS, it's next to unusable in stock. So, to include a coast, we need two additional constraints (to determine when to start coasting and when to start circularizing). But if circularization dV is fixed (i.e. Ap and Pe of suborbital trajectory already defined), then only one constraint is needed to decide when to start coasting. The constraint is obviously the minimal tgo and I don't have the idea how to find the final altitude from this.
  14. @Jim DiGriz thanks for the PDF. I figured what my problem was - I forgot to apply rgo,z correction (chapter 4.5 in 19740004402). After I included it, the convergence is good. Examining this, I drew another conclusion. Correction looks as follows (lambda denoted as L): rgoz = iz (S - (L, rgoxy)) / (L, iz). Then, substitute rgoxy = rgo - (iz, rgo) iz. rgoz = iz ( S - (L, rgo) + (iz, rgo) (L, iz) ) / ( L, iz ) = iz ( S - ( L, rgo ) ) / ( L, iz ) + iz (iz, rgo). then, the next correction (omitting the rbias): rgo = rgoxy + rgoz = rgo - (iz, rgo) iz + iz ( S - ( L, rgo ) ) / ( L, iz ) + iz (iz, rgo) = rgo + iz ( S - ( L, rgo ) ) / ( L, iz ) meaning that a) separate calculation of rgoxy is redundant and b) iz doesn't even need to be normalized. If your tangent vector has the wrong sign the first thing to triple-check is cross-products. Also, I'd use projection of r into target plane in the initialization instead of r itself. As for computation of rthrust and vthrust, that's the same decomposition into phi written differently. The main difference in rgo computation from 19740004402 is whether rbias is added before or after downrange correction. I don't think it changes too much.
  15. I've tried to rewrite the algorithm and apply it for stock system. And the first iteration just doesn't converge. Also, vbias is insanely large. Looking at output values, (dot lambda) magnitude on the first iteration is around 0.03 with tgo about 180 sec, so (dot lambda) * tgo has magnitude > 1. Is the divergence of first iteration expected then because I'm outside the initial assumptions' validity range?