Part 2: Lunar Descent

If you have finished tinkering with the Planetoids lab you can continue with this lab where we will now add gravity to the game! You have a little ship that you must fly around and land safely on the moon. If you approach the landing too fast you will crash the ship.

This example will use a programming language that is practically indistinguishable from C and C++ programming. (Note: If you are familiar with C or C++ the main difference you will see is that there is no main() function and instead the draw() function serves this role.)

The code is designed to solve the kinematic equations relevant to this case. $$\sum F_{\rm{net},x} = F_{\rm thrust} \cos \theta = m \, a_x$$ $$\sum F_{\rm{net},y} = F_{\rm thrust} \sin \theta - m g = m \, a_y$$ $$ \Delta v_x = a_x \Delta t$$ $$ \Delta v_y = a_y \Delta t$$ $$ v_x = v_{x0} + \Delta v_x$$ $$ v_y = v_{y0} + \Delta v_y$$ $$ x = x_0 + v_x \cdot \Delta t $$ $$ y = y_0 + v_y \cdot \Delta t $$

The computer program we will work with here computes these equations over and over again, updating $v_x$, $v_y$, $x$ and $y$ depending on whether the thrust is turned on or off. If the thrust is turned off then $a_x = 0$ and $\Delta v_x = 0$ and the ship just continues with the same $v_x$ velocity. With the thrust off the $v_y$ velocity will continue to change with time due to gravity, $\Delta v_y = g \, \Delta t$.

Step 0. Open up 2D planetoids in an editor

Click on this link to open the 2D planetoids code in a p5.js editor

Press play there to run the code. It should look the same as it did with the at the end of the planetoids exercise

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

In the top left corner, press and you'll see something like this:

If the program can detect that something is wrong with your code it will show a red next to that objective.

If the program can detect that you have completed the objective it will show a green check mark next to that objective.

But the program is not very smart and if it can't tell whether you have completed the objective it will indicate a question mark like this next to that objective.

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. Add gravity to planetoids

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;

Right before the display(); function, add this line:

deltaVy += g*dt;

Note that gravity points in the $-y$ direction, so we need a minus sign in the above code to make sure down is negative (and since $g > 0$).

You've added gravity to our simple planetoids game! Now run the program by clicking . The program should behave like this.

Step 2. Add the Game Over!

Edit your code so that it's game over if the ship falls through the bottom of the page. Since down is positive, this happens if the y value becomes larger than the height of the screen.

Right after display(); add this line:

  if (y < 0) {
  drawText('Game Over!',width/2,height/2);
  exit();
  }

Great, now there is a way to lose the game! The program should now behave like this.

Step 3. Add a way to win the game!

We need to add a way for the ship to land on the surface of the moon.

Add this code right after the display(); function to draw a line at the bottom of the page:

drawLine(0,0,width,0);

If you play the game now there should be a black line on the bottom of the screen. You should test it to see if this worked.

Now we need a way for the ship to sit in the surface of the moon. In real life, the surface of the moon would provide a normal force to hold up the ship. We could try to code up the normal force, but a simpler thing to do would be to make it so that if the ship gets very close to the bottom then the acceleration and velocity will be zero in both the x and y direction. The ship will just sit there forever.

Add these line right before the game over in draw()

 if ( abs(y - 0.03*height)  < 0.1) {
  deltaVx = 0;
  deltaVy = 0;
  vx = 0;
  vy = 0;
  theta = 3.141/2;
  drawText('You Win!',width/2,height/2);			      
  }

Among other things, the above code will change the angle of the ship from 0 to $\pi/2$ radians. If you convert from radians this would be 90 degrees.

Note that the accelerations are set to zero, the velocities are set to zero and the angle of the rocket points straight up.

If you've coded up everything correctly, the end result should behave like this.

Step 4. Change the initial angle!

There are a number of different options to customize the game. You can change the initial direction of the ship from horizontal to vertical by changing one line of your code.

Near the beginning of your code change this line:

theta = 0; 
to this:
theta = 3.141/2;

The above code will change the angle of the ship from 0 to $\pi/2$ radians. If you convert from radians this would be 90 degrees.

Step 5. Let the ship fall to the ground! Calculate the free fall time

If you don't fire the thrusters the ship will fall to the ground. Let's measure how long this takes in the program, and then use our physics knowledge to see if the measured time makes sense.

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 5b. 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_i + v_{yi}t + \frac{1}{2} g t^2$$

where $y_i$ is the initial height, $v_{yi}$ 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 6. Just for fun give the ship a random initial velocity

You can give the ship a random velocity by changing vx and vy at the beginning of the program from this:

  vx = 0;
  vy = 0;
to this:
  vx = random(-5,5);
  vy = 0;
Go ahead and change this code to make the game more fun (5 is pretty arbitrary, what would be a more fun choice? what about giving vy a random velocity?). What did you change this part of the code to?

Optional Challenges: SpaceX landing!

Challenge #1. Just for fun, change g back to -9.8 (instead of -1.67) so that the rocket is trying to land on earth instead of the moon. You can increase the value of Fthrust 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. Can you modify the code so that the rocket fires the thrusters automatically so that it lands by itself without any human guidance? This is what the computers on the spaceX rockets have to do.

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

1. Make sure you can lose the game and win the game

As described in steps 2 and 3

2. Make sure to change the initial angle

Make sure to change the initial angle to 3.141/2 as described in step 4.

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

In step 5 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. Give the ship a random velocity

Change the beginning of the code to give the ship a random velocity as described in Step 6.