Project Launch MFD development thread

In the aviation industry the following usage has, in general, been followed for the past 20+ years. In simple terms:

Navigation: Determining your location, velocity, acceleration. Uses sensor data as input. Examples of navigation data displays are the Orbit MFD and the Map MFD.

Guidance: Determining the course you need to fly to get where you want to go. Uses navigation solution and flight plan as inputs. An example of guidance is the Transx MFD.

Flight Control: Physically maneuvering the craft to get you there. Uses guidance and navigation as inputs. Examples of flight control are the basic DG autopilot modes, the Auto-docking feature of the DG-IV and various modes of the IMFD.
 
When people were talking about PEG Autopilot, they were talking about [ame="http://www.orbithangar.com/searchid.php?ID=2783"]an autopilot[/ame], which uses PEG guidance algorithm's output as input for the autopilot itself.

Whenever we talked about an autopilot for Launch MFD, we meant the feature that Launch MFD currently lacks.
 
Target pitch is now displayed also in the Compass mode, in the MFD area, for VESSEL ships.

launch-mfd-1.2.8-pitch-in-compass.png
 
I've added support for multiple vessels, thanks to slightly modified Computerex' code, provided on OrbiterWiki

Now, each vessel has its own target and configuration. Sound configuration is common.
 
This is a reply to caningo from this thread:
http://orbiter-forum.com/showpost.php?p=60281&postcount=3

OK, here we go. Firstly I'd ask you to read section 7 (Direct ascent theory) of Launch MFD's documentation:
http://www.elwico.pl/~ender-sz/orbiter-pdf/pliki/LaunchMFD-doc.pdf
and to play around with the direct ascent visualisation app:
http://www.elwico.pl/~ender-sz/orbiter-pdf/pliki/LaunchMFD-da-solver.zip
just that we understand each other better.

Implementation details in short:
The main ideas behind my algorithm is that you start accelerating at one point of time, and once you've reached about half of orbital velocity, you fly constantly, until there's a good time for plane change manouevre. In the time of your flight satellite's position is updated, and the distance is checked upon insertion. In this part you move fast, as much as the satellite. If the distance is big, the program tells you to wait on the pad further. You move with merely 460 m/s, while the station moves relatively rapidly. Say you move with that speed for 50 seconds, thus the station covered 7700 * 50 m. and you 460 * 50, thus this is a method of regulating the final distance again, as the previously described loop is run for every other subsequent 50s. Once the distance's sign changes, the program waits 25 s less (50/2) then 12.5 more (25/2) and so on, until the distance is minimised.

Now I fully accept that your Prof.'s info may influence a total change in my approach, in particular I expect that the trajectory may be different in a realistic approach (it may be more oval), but assuming I could still make a good prediction with the current model, I think it's reasonable to formulate questions regarding it:

  1. In the turning phase, I use the following kinematic equations to predict the covered distance in a given iteration (its an inner loop, which I haven't described here, only in the documentation):
    Code:
    vel[0] = prev_vel[0] + at * cos(azimuth);  // ship's y velocity 
    vel[1] = prev_vel[1] + at * sin(azimuth);   // ship's x velocity
    double at2_2 = initialAccel * t * t / 2;
    sshy = sshy_prev + vel[0]*t + at2_2 * cos(azimuth);  // ship's y path
    sshx = sshx_prev + vel[1]*t + at2_2 * sin(azimuth);  // ship's x path
    Are these equations correct? The question is regarding the cos and sin parts. I don't know whether to multiply them in both vel and s, or just in one of those variables (if so then in which one?)
  2. What to do about the necessary altitude gain? Currently my program assumes that you gain altitude with hover engines and simultaneously gain tangential velocity with mains (2D problem again). If we wanted to allow for a pitch down ascent and we still wanted to keep it 2D, my idea would be to use a variable tangential acceleration, which would grow as you were pitching down.
  3. Another thing about altitude gain is that the 2D problem solver specifies a constant velocity in the middle of your flight. The problem is that as you gain altitude, your tangential velocity changes... Should you have that given velocity close to the surface, or on the desired alt? I think that the latter.
    All that makes me think that it's impossible to perform a direct ascent perfectly thanks to a static calculation, and it would need to be continously recalculated in a seperate thread.
  4. Perhaps the Prof. would know what to do about the problem that the ship must launch from equator. What I need to know is how to plot a ship's path from a top down view, like it's done in Map MFD. I perform equatorial launches because your trajectory is not sinusoidal along the equator... at least before you start to turn. The latter must have a big contribution in final distance error. If he/her doesn't know it, then it's OK. I'm sure that other Orbiter users can answer that.

It would be also important to tell the lecturer what tools we already have:
- PEG algorithm and on-the-fly correction
- Inclination on-the-fly correction
- Off-plane (LAN) on-the-fly correction
I think that these three could be combined in a way that would allow a move into a 3D problem.

[EDIT]
If there's anything unclear in my questions or explanations, shoot away.
Can you also ask the Professor for books recommendations regarding direct ascent?

Cheers! :cheers:
 
Last edited:
After a short break, here are the latest news regarding Direct Ascent program in Launch MFD, just to let you know that there's some slow, but steady progress.

I wanted to make the program more flexible, by allowing pilot to choose launch site latitudes other than equatorial. For this, I'd have to be able to calculate a thing or two in the so called Great Circle environment, namely: a true distance between two points on a sphere (not a straight line), which was quite easy thanks to Wikipedia, and the harder part - drawing the Great Circle on a 2D map by being able to define arbitrary point of a geodesic for navigational purposes. I've done some googling, and surprisingly not much info is available on this matter. Only some well positioned - fish givin' - code not showin' applications, so I've decided to change this :)
Luckily I've come across a post on mathforum.org explaining a possible solution of this problem, so I've fired up Scilab and started experimenting...:

great-circle.png


The "Chinese fans" on the left are starting and ending points of a journey on a sphere with arbitrary points between them. They are defined by spherical coordinates, converted to cartesian coordinates and finally multiplied by a value big enough so that they all have a length equal to radius of the planet. The rightmost trajectory is the longest one - almost from 0 to 180 degrees.
On the right, you see the famous Map MFD plots, with the longest one being the (0, 180) trajectory. They are the cartesian points, converted back to spherical coords and shifted accordingly, so they represent geographical coords. The black plots are the actual trajectories from A to B, while the blue plots are the planet's other side's counterparts.

My code could also be used for implementing something like Free Map MFD 2006 or something.

Here's a Scilab script which plots these beauties :) :

Code:
clear
r = 2;

offset = 0;
//offset = %pi/2;
// geographic coordinates
// 1 - starting point
// 2 - ending point

// latitude should be in range (-%pi/2, %pi/2)
// if displaying a satellite, lat1 is inclination
// divide the path into 2 steps - from 1 to 2 and from 2 to 3
// Increases precision greatly
lat1 = 51.57 * %pi / 180; 
lat2 = 0;
//lat1 = 0.28 * %pi / 2; 
lat3 = -lat1; // opposite side of the panet (can be changed)

// longitude should be in range (-%pi, %pi)
lon1 = -90 * %pi / 180;
lon2 = lon1 + %pi/2;
lon3 = lon2 + %pi / 2; // opposite side of the panet (+ PI) (can be changed)
// converting to spherical coordinates

// theta should be in range of (0, %pi)
theta1 = lat1 + %pi/2;
theta2 = lat2 + %pi/2;
theta3 = lat3 + %pi/2;

// phi should be in range of (0, %pi) (??)
phi1 = 0;
phi2 = lon2 - lon1;
phi3 = lon3 - lon1;



// convert to cartesian coordinates
x1 = [0, r*sin(theta1)*cos(phi1)];
y1 = [0, r*sin(theta1)*sin(phi1)];
z1 = [0, r*cos(theta1)];

x2 = [0, r*sin(theta2)*cos(phi2)];
y2 = [0, r*sin(theta2)*sin(phi2)];
z2 = [0, r*cos(theta2)];

x3 = [0, r*sin(theta3)*cos(phi3)];
y3 = [0, r*sin(theta3)*sin(phi3)];
z3 = [0, r*cos(theta3)];

// create vectors for easy calculations
v1 = [x1(2), y1(2), z1(2)];
v2 = [x2(2), y2(2), z2(2)];
v3 = [x3(2), y3(2), z3(2)];

// actual path
vTheta12 = []; // 1st quart
vPhi12 = []; 
vTheta23 = []; // 2nd quart
vPhi23 = []; 

// mirrored path
vPhi34 = [];

vPhi41 = [];

fixedStep = 0.02;
i = -fixedStep;
step = fixedStep;
// here, we'll be changing i from 0 to 1 
// to properly scale a resulting vector below...
while (i <= 1)
  // just a variable precision
  i = i + step;
  if i > 0.30 & i < 0.70
    step = fixedStep/2;
  else
    step = fixedStep;
  end

  // the meatball equation of this approach:
  // From v1, draw a vector to v2 and multiply it from 0 to 1
  // so that we have many "straight line" points between p1 and p2
  // on a plane defined by p1, p2 and origin of the planet (0,0,0)
  v12 = v1 + i * (v2 - v1);
  v23 = v2 + i * (v3 - v2);
  // check the length of the new point's vector
  r12 = sqrt(v12(1)^2 + v12(2)^2 + v12(3)^2);
  r23 = sqrt(v23(1)^2 + v23(2)^2 + v23(3)^2);
  // make the vector as long as planet's radius
  v12 = v12 * r / r12;
  v23 = v23 * r / r23;
//  rtest = sqrt(vtest(1)^2 + vtest(2)^2 + vtest(3)^2);
  // for plotting
  x12 = [0, v12(1)];
  y12 = [0, v12(2)];
  z12 = [0, v12(3)];
  
  x23 = [0, v23(1)];
  y23 = [0, v23(2)];
  z23 = [0, v23(3)];
  scf(0);
  param3d(x12, y12, z12);
  param3d(x23, y23, z23);

  // convert to spherical
  // r - already calculated
  theta12 = acos(v12(3) / r);
  phi12 = atan(v12(2) / v12(1));
  
  theta23 = acos(v23(3) / r);
  phi23 = atan(v23(2) / v23(1));
  
  // ensure proper range
  if phi12 < 0
    phi12 = phi12 + %pi;
  end

  if phi23 < 0
    phi23 = phi23 + %pi;
  end

  // add new calculations to a vector
  vTheta12 = [vTheta12, theta12];
  vPhi12 = [vPhi12, phi12];
  vTheta23 = [vTheta23, theta23];
  vPhi23 = [vPhi23, phi23];
  
  //vPhi3 = [phi, vPhi3];
  //vTheta3 = [theta, vTheta3];
  
  // mirror path (on the other side of planet)
  phi34 = phi12 + %pi;
  vPhi34 = [vPhi34, phi34];
  phi41 = phi23 + %pi;
  vPhi41 = [vPhi41, phi41];
end

// draw the final line with a different color
param3d1(x12, y12, list(z12, [3,2]));
param3d1(x23, y23, list(z23, [3,2]));
  
//vTheta = [vTheta, theta2];
//vPhi = [vPhi, phi2];
// convert back to geographical

vTheta12 = vTheta12 - %pi/2;
vTheta23 = vTheta23 - %pi/2;
// use the initial longitude 
vPhi12 = vPhi12 + lon1 + offset;
vPhi23 = vPhi23 + lon1 + offset;

vPhi34 = vPhi34 + lon1 + offset;
vPhi41 = vPhi41 + lon1 + offset;

// ensure proper ranges
s = size(vPhi12);
for i = 1:s(2)
if vPhi12(i) >= %pi
    vPhi12(i) = vPhi12(i) - 2*%pi;
end
if vPhi23(i) >= %pi
    vPhi23(i) = vPhi23(i) - 2*%pi;
end
if vPhi34(i) >= %pi
    vPhi34(i) = vPhi34(i) - 2*%pi;
end
if vPhi41(i) >= %pi
    vPhi41(i) = vPhi41(i) - 2*%pi;
end

end


scf(1);
// draw equator
plot2d([-%pi %pi], [0 0]);
// draw the actual trajectory from point 1 to 2
plot2d(vPhi12 ,  vTheta12, style=1,  rect=[-%pi, -%pi/2, %pi, %pi/2]);
plot2d(vPhi23 ,  vTheta23, style=1,  rect=[-%pi, -%pi/2, %pi, %pi/2]);
//plot2d(vPhi3 ,  -vTheta3, style=1,  rect=[-%pi, -%pi/2, %pi, %pi/2]);
// draw mirror on the other side of planet
plot2d(vPhi34, -vTheta12, style=-2, rect=[-%pi, -%pi/2, %pi, %pi/2]);
plot2d(vPhi41, -vTheta23, style=-2, rect=[-%pi, -%pi/2, %pi, %pi/2]);

// just a test of distance calculation
R = 6378;
D = acos( sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lon2 - lon1) ) * R;
 
Last edited:
Hi enjo. I've just installed new Danstephs addons for OB2010 and found incompatibility of Launch MFD with it: onscreen HUD(orbit, surface, dock) is not working in such scenarios.

You can find me at #orbiter for any details..
 
Last edited:
Launch MFD hooks a vessel's clbkDrawHUD function and this hooking may be interfering with whatever Dan's addon is doing with the HUD. Try this:

1. Launch the scenario you are interested in.
2. Open Launch MFD, press the HUD button to turn off Launch MFD's HUD display.
3. Close the simulation.
4. Launch the (Current State) scenario.

Does that help? (Disclaimer: I'm just working on a hunch here, I have not read Launch MFD's code)
 
Fixerger:
I don't have time for IRC except during weekends. Does the problem exist with Launch MFD for Orbiter 2009 RC1?
 
Enjo, that problem appears on beta 2010 (that was tested, for 2006 i don't know).

tblaxland, don't help, anyway HUD in Launch MFD is disabled for beta and i can't see it.
 
Last edited:
I'm asking about Launch MFD version... Look at my signature
 
OK, thanks then, but I can check that later because I'm preparing for exam session now.

---------- Post added at 06:28 PM ---------- Previous post was at 08:13 AM ----------

OK. Confirmed, fixed and uploaded. Thanks again :)
 
Great job enjo! It works now.
 
Last edited:
Warning! Headache hazard.

I've updated the script in the first post of this page. Now it accepts input as geographical coordinates in range (-PI, PI) for longitude and (-PI/2, PI/2) for lattitude, then properly operates on them to have their spherical equivalents in proper ranges by setting starting point to 0 and adding starting point to final point, does the usual tricks, and in the end, when the results are returned, it shifts the coords back to the range as they were in the beginning.

Because it accepts geo coords, it's better prepared for operating in Orbiter.

Here is how it looks like with Map MFD for comparison and using the same input data:

great-circle-map.png


The tilted crosses are the mirror path on the other side of the planet.

When I have time, I'll try to add this to my windowed DA solver and after all tests pass well, I'll use it in Launch MFD.

On the other news, McWgogs gave me an interesting idea: allowing to choose a target on the ground and drawing the great circle for this target, then giving the pilot a proper guidance as usual (looks like he wants to nuke his house again!). I'd do it in a new Launch MFD page, like Compass and DA, I think.

---------- Post added 01-24-10 at 12:45 PM ---------- Previous post was 01-23-10 at 09:36 PM ----------

Some progress :) Let me share this before I drop the project for about two weeks because I need to prepare for exams. Here's the great circle of ISS calculated in a C++ program - my direct ascent solver, which shares the most important code with Launch MFD:

da-solver01.png



Unfortunately, to your dissatisfaction, the great circle will be the last feature that gets rid of any simplifying assumptions, ie. that the ship starts from equator and the world is flat. I need to graduate first, and if I started going too deep into physical matters, I could end up deep in a dark forest, because it could be beyond me. On the other hand, the graduation part of the project will also be useful for Launch MFD - it will be AI based decision making about, for example, how great your eastern velocity should be to minimise fuel usage, because the faster you fly, the lesser the gravity well effect has on you, the shorter time you spend in it countering the gravity, but the harder it will be to turn the ship to the desired inclination. Sounds like a perfect AI test subject to me :)
 
Last edited:
Heh, plotting great circle for the whole range is one thing. Defining a precise point on it at which an object is after passing certain distance is another.

Here is how the algorithm can be visualised now:

da-solver03.png



My good friend's comment after he saw this was: "Looks great, Simon, but I don't know what I'm seeing...". To suppress such comments, here's the description:

The rightmost great circle and black asymptote are of the station, and the leftmost GC and red asymptote are of the ship. The red one will help in directing velocity vector seen in the middle which is now [x,y] = [1,0] normalised. This will determine exactly how much you have to turn to hit the target. Note how many possible situations you can have when you for example simply shift station's orbit left or right. For just one pair [inclination, latitude], shifting the orbit can have drastic impact on transfers, ranging from soft turns to much harder ones, like on the picture. I think that I don't need to mention how big impact this has on fuel usage, hence how many possibilities for optimisations it allows for.


Technical stuff: ( for Zachstar :P )
I'll save you telling about how many methods I was trying out for locating object on GC, because all of them failed except the latest one: calculating the actual spherical angles numerically. Now imagine how the Scilab script was doing this: it created a vector in 3D space from initial position to final, and was dividing this vector into equal parts... yeah, the vector, not the actual path - that one had a variable precision.
In this approach, I assume that I know how great the distance is for a given iteration. Although it's a distance on a sphere, we only care about its magnitude. So we have this, divide it by planet's radius and we have an angle. Now we know how much of the whole path has been passed. We pass this angle to a subroutine which calculates numerically an angle in 3D space between starting point and searched point. Numerically, means that we increment the angle slightly, each time checking if it's big enough. Here's the fix:

Code:
double angPassed = angRatio * PI/2; // angRatio varies from 0 to 1
    double u [3];
    double alpha = 0;
    gcFixIter = 0; // could be not reset for optimisations, but then it should be decremented instead of incremented
    do
    {
      double n [3];
      for (int i = 0; i < 3; i++)
      {
        u[i] = ( v1[i] + gcFixIter * ( v2[i] - v1[i] ) );
      }
      cross(v1,u, n); // cross product of v1 and u - vector in question
      alpha = asin( len(n) / (len(v1) * len(u)) ); // angle between the two vectors
      gcFixIter += 0.001; // keep incrementing the angle until we reach the real distance passed
    } while( alpha < angPassed && gcFixIter < 1);

    double ru = len(u);
    for (int i = 0; i < 3; i++)
    {
      u[i] *= rad / ru;
    }

    theta12 = acos(u[2] / rad);
    phi12 = atan(u[1] / u[0]);
and without the fix, the previous method in C:

Code:
double v12 [3];
    for (int i = 0; i < 3; i++)
    {
      v12[i] = ( v1[i] + it * ( v2[i] - v1[i] ) );
    }
    double r12 = len(v12);
    for (int i = 0; i < 3; i++)
    {
      v12[i] *= rad / r12;
    }
    theta12 = acos(v12[2] / rad);
    phi12 = atan(v12[1] / v12[0]);
Of course, the "unfixed" method is still good for plotting the whole range, because it has much less overhead, since it doesn't use the numerical solving.
 
A quick and more of a visual info:

The Jay-transfer :)

da-solver04.png


That's all for now. No time to waste.
 
New screenshots:
da-solver05.png


Note how the "launch azimuth" changes along the path as the ship "descends" on the map, to be able to hit the final inclination from the current position.

To see the influence of an initial distance to satellite's orbit plane, check out the next pic:

da-solver06.png


Here you can see that the final trajectory is not as curved as before because of lesser relative angle between planes (LAN change).

An insightful reader will also note that compared to the picture in previous post, I'm not aiming for the tangent anymore, but the actual satellite's path, which is the main achievement of this update :) It involved some 3D math. To show things clearer, here's just the final trajectory:

da-solver07.png



Soon I'll be able to give this app away for people to play around, but first I must let it process arbitrary ranges of input data.
 
Back
Top