Search

Mars Lander, Take II: Crashing onto the Surface

In
my last article, I spent almost the entire piece exploring gravitational
physics, of all unlikely topics. The focus was on writing a version of the
classic arcade game Lunar Lander, but this time, it
would be landing a craft
on the red planet Mars rather than that pockmarked lump of rock orbiting
the Earth.

Being a shell script, however, it was all about the physics, not about the
UI, because vector graphics are a bit tricky to accomplish within Bourne
Shell—to say the least!

To make the solution a few dozen lines instead of a few thousand, I
simplify the problem to two dimensions and assume safe, flat landing
spaces. Then it's a question of forward velocity, which is easy to
calculate, and downward velocity, which is tricky because it has the
constant pull of gravity as you fire your retro rockets to compensate and
thereby avoid crashing onto the planet's surface.

If one were working with Space X or NASA, there would be lots of factors to
take into account with a real Martian lander, notably the mass of the
spacecraft: as it burns fuel, the mass decreases, a nuance that the
gravitational calculations can't ignore.

That's beyond the scope of this project, however, so I'm going to
use some highly simplified mathematics instead, starting with the one-dimensional problem of descent:

speed = speed + gravity
altitude = altitude - speed

Surprisingly, this works pretty well, particularly when there's
negligible atmosphere. Landing on the Earth's surface has lots more
complexity with atmospheric drag and weather effects, but looking
at Mars, and not during its glory days as Barsoom, it's
atmosphere-free.

In my last article, I presented figures using feet as a unit of measure, but
it's time to switch to metric, so for the simulation game, I'm using
Martian gravity = 3.722 meters/sec/sec. The spaceship will enter the
atmosphere at an altitude of 500 meters (about 1/3 mile), and players have
just more than 15 seconds to avoid crashing onto the Martian surface, with a
terminal velocity of 59m/s.

Since I'm making game out of it, the calculations are
performed in one-second increments, meaning that you actually can use the
retro rockets at any point to compensate for the tug of gravity and
hopefully land, rather than crash into Mars!

The equation changes only a tiny bit:

speed = speed + gravity + thrust

Again, there are complex astro-mechanical formulas to figure out force
produced in a retro rocket burn versus fuel expended, but to simplify,
I'm assuming that fuel is measured in output force: meters of counter
thrust per second.

That is, if you are descending at 25 meters/second, application of 25 units
of thrust will fully compensate and get you to zero descent, essentially
hovering above the surface—until the inexorable pull of gravity begins to
drag you back to the planet's surface, at least!

Gravity diminishes over distance, so too much thrust could break you
completely free of the planet's gravitational pull. No
bueno. To
include that possibility, I'm going to set a ceiling altitude. Fly
above that height, and you've broken free and are doomed to float off
into space.

Floating-Point Math

Shell scripts make working with integer math quite easy, but any real
calculations need to be done with floating-point numbers, which can be
tricky in the shell. Therefore, instead of using the
$(( )) notation or
expr, I'm going to tap the power of
bc, the binary
calculator program.

Being in a shell script, it's a bit awkward, so I'm going to use a
rather funky notational convenience to constrain each calculation to a
single line:

speed=$( $bc <<< "scale=3; $speed + $gravity + $thrust" )

By default, for reasons I don't understand, bc also
wants to work with just integer values, so ask it to solve the equation
1/4,
and it'll return 0. Indicate how many digits after the decimal place to
track with scale, however, and it works a lot
better. That's
what I'm doing above with scale=3. That gives three digits
of precision after the decimal point, enough for the game to function fine.

Martian Lander Core Code

With that notation in mind, I can finally code the basics of the Martian
lander:

Obviously, there are a lot of variables to instantiate with the correct
values, including gravity (–3.722), altitude (500 meters), thrust (retro
rockets start powered down, so the initial value is 0), and speed and time
also should both be set to 0.

Even with this tiny snippet, however, there are some problems. For example,
the conditional that controls the while loop tests whether altitude is
greater than zero. But altitude is a floating-point number, so the test
fails. The easy solution is a second variable that's just the integer portion
of altitude:

alt=$( echo $altitude | cut -d\. -f1 )

One problem solved.

Thrust is the force being exerted by the rocket when it's firing, so
that'll have to be something the user can enter after each second (the
"game" part of the game). But once it's fired, it should shut
off again, so thrust needs to be set back to zero after each calculation is
complete.

There's also a tricky challenge with positive and negative values here.
Gravity should be a negative value, as it's pulling the craft inexorably
closer to the center of the planet. Therefore, thrust should be positive,
since it's fighting gravity. That means speed will be negative when
dropping toward the surface, and positive when
shooting upward, potentially escaping the planet's gravity field
entirely.

At this point, the craft is dropping at 55m/s and is only 53 meters above
the surface of the planet, so you can count on a big, ugly crash. BOOM!

At second 15, you could apply 55 units of thrust to jerk the craft back to
zero speed, but what if you didn't have 55 units of fuel or if the max
thrust you could exert at any given unit time was 25 due to rocket design
(and passenger survival) constraints?

That's where this gets interesting.

In my next article, I'll dig into those constraints and finally add some
interactivity to the program. For now, be careful out there flying this
particular space craft. It's your budget that the replacement parts are
coming out of, after all!

Props to Joel Garcia and Chris York for their ongoing assistance with all
the gravitational formulas. Any errors and glitches are all due to my own
rusty physics.

Dave Taylor has been hacking shell scripts on UNIX and Linux systems for a
really long time. He's the author of Learning Unix for Mac OS
X and Wicked Cool Shell Scripts. You can find him on Twitter
as @DaveTaylor, and you can reach him through his tech Q&A site: Ask Dave Taylor.