Apollo moon landing

If you have finished tinkering with Accelerate the blob you can continue with this lab where we will now add gravity to the game! The goal is to gently land the the little blob on the ground. Just for fun we will use the moon's gravity instead of earth's gravity. The result will be a lot like the Apollo moon landing.

Step 0. Open up a modified version of Accelerate the blob in an editor

Click on this link to open up a modified version of accelerate the blob in an editor

Very Important: Log in to your account! Then click "Duplicate" so you can have your own version of the code!!!

Press play there to run the code. It should look similar to the end of the accelerate the blob exercise.

By the end of this activity your goal is to have green check marks next to all the objectives like this:

The steps below will help you achieve all these objectives

Step 1. Look at the code

There are a few important differences between this code and the accelerate the blob code that you should look at before jumping into this activity. The most important one is that the arrow keys now control the applied force instead of controlling the acceleration. Imagine that the arrow keys control the thrusters on a spacecraft that is out in deep space (no gravity ... yet, that's coming in Step 2).

Here is the code:

function draw(){

    // Update velocity
    vx += ax*dt;
    vy += ay*dt;
   
    // Update location
    x += vx*dt;
    y += vy*dt;

    // Force from rocket thrust is zero unless keys are pressed
    Fx = 0;
    Fy = 0;

    // Thrust the ship depending on what key is pressed
    if (keyIsDown(LEFT_ARROW)) {
        Fx = -15;
    }
    if (keyIsDown(RIGHT_ARROW)) {
        Fx = 15;
    }
    if (keyIsDown(UP_ARROW)) {
	Fy = 15;
    }
    if (keyIsDown(DOWN_ARROW)) {
	Fy = -15;
    }

    // Draw axes and other stuff
    // This will clear the screen and re-draw it
    display();

    Fnetx = Fx;
    ax = Fnetx/mass;

    Fnety = Fy;
    ay = Fnety/mass;
    
    drawLander(x,y,vx,vy,ax,ay);
    drawForce(x,y,Fx,0);
    drawForce(x,y,0,Fy);
  
    // Add more graphics here before the end of draw()
 
} // end draw()   DO NOT ADD ANY CODE PAST THIS LINE!!!!

Thing to think about #1: Compare this to accelerate the blob? What are the differences?

Thing to think about #2: Why does the code use ax = Fnetx/mass and ay = Fnety/mass instead of ax = Fx/mass and ay = Fy/mass?

Step 2. Add gravity to the modified version of accelerate the blob

Step 2a. Add the constant g to the beginning of the code

After you click duplicate! edit the beginning of the code, add the gravitational constant for the moon. The moon's gravity is 1/6th of the earth's, so g = -9.8/6 = -1.63 m/s2

Add this line to near the beginning of your code:

g = -1.63;

Step 2b. Change Fnety to include the weight of the ship

To add gravity to the code, we CAN'T just set ay = g. This would make the ship accelerate towards the ground like we want (feel free to try it out!), but this approach will NOT let us fire the thrusters to slow our descent. We are going to need to do something a bit more clever than that.

The clever (and right) way of adding gravity to the code is to remember these three facts:

1. gravity is a force

2. The force of gravity is the weight

3. The net force is the sum of all the forces

This means that we need to replace this code Fnety = Fy; with something else:

W = ?????; // what goes here?
Fnety = Fy + W;

Your job is to figure out what the ???? should be!

If you make these changes correctly your program should behave like this

Step 3. Add a game over

Modify your code so that it's possible to crash on the ground (which is at y = 0). Since up is positive and down is negative, add an if statement that checks if y < 0 like you see below.

Somewhere after display(); add this code:

  if (y < 0) {
  drawText('Houston we have a problem!',width/3,height/2);
  exit();
  }

Try it out! Your program should behave like this

Step 4. Add a way to detect if you have landed safely

Here is some code you can use to detect if you've landed safely on the ground.

Somewhere after display(); add this code:

  if ( abs(y - 20)  < 0.1) {
    drawText('The Eagle has landed!',width/3,height/2);		      
    ax = 0;
    ay = 0;
    vx = 0;
    vy = 0;
    exit();
  }

If you add this to your code correctly your program should behave like this

Step 5. Add a timer!

Let's add some code to keep track of how much time has elapsed. At the beginning of the code where all the variables are initialized add this line:

t = 0;

Somewhere after the display() function add these lines:

t += dt;
drawText("time = ",0.75*width,0.75*height);
drawText(t,0.85*width,0.75*height);

Now run the code and let the ship fall to the ground. How long does it take?

Step 6. Use your physics knowledge to check if the free fall time is correct

It is always a good exercise to check that your code is giving you the same answer that you expect. Crunch some numbers to see if the free fall time is correct. You'll probably want to use this equation: $$y(t) = y_0 + v_{0y}t + \frac{1}{2} g t^2$$

where $y_0$ is the initial height, $v_{0y}$ is the initial speed and $g$ is graivitational acceleration.

Disclaimer #1: Don't forget that the ship is landing on the moon! Use g = -1.63 instead of g = -9.8!

Disclaimer #2: Unless you modified the code, the ship will start from y = 250 and hit the ground at y = 0

Step 7. Calculate the Fractional Error

Once you have calculated the free fall time, compare it to the free fall time you measured from the program by calculating the fractional error: $$ \% = 100 \cdot \frac{|{\rm meas} - {\rm true}|}{\rm true} $$

Make sure to treat the free fall time from the simulation as the measurement, not the "true" value which comes from the equations. We are trying to check if there are any bugs in our code!

Step 8. Give the ship a random initial velocity

In the actual apollo moon landings the lander did not start from rest. There would have been an initial velocity both horizontally and vertically. We can include this in our code (and make it a bit more fun) by initializing the ship with a random velocity.

Near the beginning of the code replace vx = 0; and vy = 0; with this:

vx = random(-20,20);
vy = random(-20,20);

If you add this to your code your program should behave like this

At this point your code should have all green check marks! Yay!

Challenges!

Challenge #1. SpaceX challenge

Just for fun, change g back to -9.8 (instead of -1.63) so that the rocket is trying to land on earth instead of the moon. You can increase the value of Fx and Fy (in other words the thrust) if you need to. This situation is what SpaceX has to deal with when they land their rockets on a landing pad. Can you land the ship even in this situation?

Challenge #2. Keep track of your fuel

There is only so much fuel that you can bring on a ship to try to land on the moon. Famously, during the first moon landing the ship nearly ran out of fuel to land.

Pick a number for how many seconds of fuel that your ship has (30 seconds?) and subtract from that number any time you press the thrusters. Configure your code so that when you run out of fuel the thrusters don't work any more.

Challenge #3. Show thrusters

The program would be a little bit more fun if you could see the thrusters firing when you press the arrow keys.

The simplest way to do this is to have a triangle show up when different arrow keys are pressed. In this code there is a triangle function you can use that works like this:

drawTriangle(x1,y1,x2,y2,x3,y3,rgbcolors);

You can see in the above that there are three points (x1,y1), (x2,y2), and (x3,y3) that are connected together to create the triangle.

There are a few steps to get this to look like fire when you press up arrow.

1. Move display() to right before the if statements

Any graphics you write to the screen will get cleared by the display() function, so move display() earlier to avoid that problem

2. Turn off the milestones/objectives

Unfortunately, moving the display() function will make some of the milestones stop working. If this bothers you, just turn off the milestones by adding this line to the beginning of your code where the variables are set to their initial values:

showmilestones = false;

3. Add drawTriangle to the if statement for up arrow

Go ahead and add this code to the if statement for up arrow:

drawTriangle(x-10,y-20,x+10,y-20,x,y-40,color(255,0,0));  

So the whole if statement section looks like this:

    // Draw axes and other stuff
    // This will clear the screen and re-draw it
    display(); 
  
    // Thrust the ship depending on what key is pressed
    if (keyIsDown(LEFT_ARROW)) {
        Fx = -15;
    }
    if (keyIsDown(RIGHT_ARROW)) {
        Fx = 15;
    }
    if (keyIsDown(UP_ARROW)) {
        Fy = 15;
        drawTriangle(x-10,y-20,x+10,y-20,x,y-40,color(255,0,0));      
    }
    if (keyIsDown(DOWN_ARROW)) {
    	Fy = -15;
    }

Notice that we moved the display() function to before the if statements instead of after.

Use this color picker to change the color of the thrust from pure red (255,0,0) to something more realistic like yellow or orange (or blue!). You can even use two drawTriangle functions to draw a blue flame on top of an orange flame, etc.

Challenge #4. Lunar auto-pilot

In the apollo missions, one of the astronauts always had to pilot the ship to land on the moon (which is why a lot of the early astronauts were test pilots). Computer technology was not advanced enough at that point to have the ship land itself.

Set the gravity to lunar (g = -1.63) and try to configure the code to fire the thrusters in such a way to bring the ship down gently enough that you get the "Eagle has landed!" message instead of "Houston we have a problem!". To make it easier set the initial velocity back to vx = 0; and vy = 0;

Challenge #5. SpaceX auto-pilot

Set the gravity to earth (g = -9.8), give the ship a random intial velocity and try to get your auto-pilot to land the ship on earth. This is actually how spaceX does it! Everything happens too fast for a human pilot to bring the rocket down safely. Feel free to increase the thrust (Fx and Fy) if you need to. Good luck!

How to get full credit on this programming lab!!!

1. Describe the differences between the beginning code used here and the code in the accelerate the blob activity

2. Make sure you can land the ship and crash the ship

As described in steps 3 and 4

3. Make sure your calculation for the free fall time agrees with the simulation

In step 6 you will use your physics knowledge to calculate what the free fall time should be and compare it to the free fall time from the simulation. For a variety of reasons, we don't expect computer simulations to be perfectly accurate but in this case the two numbers should agree to better than 1%

4. Make sure to add a random initial velocity to the code

This is just to make the program more interesting, but it is required. Have fun!

5. The challenges really are optional

Feel free to try the challenges (which are pretty fun). But if you can't get to them that's ok.