The problem Launch to Orbit supposed that we perform a single launch of a single rocket to single target orbit. But perhaps we want to compete with Elon Musk and his SpaceX :) In this case we are going to deal with many space vehicles, created for many different tasks - and hence they may need to be launched to various orbits!
In this case it would be great to create some whimsical algorithm which, initialized with two input values H
and V
, shall smartly drive the rocket to the desired height and take care of it having exact velocity here,
when "parking" to the orbit.
That's exactly the scope of this new task. Use the flight simulation code given below, quite similar to one in
the previous problem - differing in the "control" part. Now it doesn't choose turning force Fa
and other
actions according to pre-written "flight plan" - instead it calls for subroutine PILOT
at every step - this
subroutine should take care of modifying the control variables.
Expected tolerance: 10 km
for altitude and 100 m/s
for velocity; direction should be no more than
0.57 degree
away from horizontal. Also note we use smaller timesteps of 1/16 second
.
Algorithm should be written in BASIC
(currently it is the only language our rocket's computer understand).
This problem is from the field of "Automatic Control Systems", which deals with controlling various mechanisms - from quadrocopters to metalworks machinery. Historically problems of this field were solved (at least attempeted) by applying curious mathematical considerations to equations describing processes. In the more recent decades computing systems become miniature enough to provide much help here, so that nowadays the process under control could re-calculate the predicted outcome many times per second and find optimal approach by using most curious approaches, ranging from small neural networks to fuzzy logic etc. The main improvement of these novelties is that processes become more "robust", i.e. less dependent on starting conditions.
All this said, there could be quite various approaches to this task. I confess that at the time of creating the task I have no ready solution myself, so I'm going to compete with others later :) If it shall happen that with the given conditions problem is not solvable we shall try to relax it in some way. Feel free to discuss at forum.
Note that the program used by the checker is similar, but tries to avoid possible collision of variables, so the only names which are going to affect the flight are:
pilot
- the name of the label marking the start of control subroutinefa
- set this to anything between -1
and +1
to apply some thrust from vernier enginesstage
- set this to 1
to reduce thrust 4
times (could be done once only)off
- set this to 1
to shut off the enginesStill other variables could (should) be read by control algorithm, particularly it needs goalH
and goalV
.
You can copy-paste this code to the solution area and run it with BASIC
button to check how well it does,
then modify the dummy pilot
subroutine in any way you like. When you submit it, only the subroutine will be
used, so there is no need to remove the main part of your code (which you use for testing).
re = 6371 * 1e3 : g = -9.81 : rem earth size and gravity
m0 = 272 * 1e3 : vm = -800 : fth = 3e6 : rem mass, fuel consumption, F thrust
dt = 1/16
att = 0 : va = 0 : fa = 0 : rem attitude (rad), speed and F turning
pi = atn(1) * 4
x = 0 : y = re : m = m0 : rem current coordinates and mass
vx = 0 : vy = 0 : t = 0 : rem current speed and time
stage = 0 : off = 0
input goalH, goalV : rem height and speed we want to reach
loop:
r = sqr(x^2 + y^2) : rem linear and turning accelerations
ag = g * (re / r)^2 : ath = fth / m
ax = ag * x/r + ath * sin(att) : ay = ag * y/r + ath * cos(att)
da = 0.001 * (m0 / m) * fa
xn = x + vx * dt : yn = y + vy * dt : rem new values for coordinates
vx = vx + ax * dt : vy = vy + ay * dt : rem new values for speed
attn = att + va * dt : va = va + da * dt : rem new attitude and its change speed
m = m + vm * dt : t = t + dt : rem reduce mass, increment time
x = xn : y = yn : att = attn : rem update coordinates and attitude
hei = sqr(x^2 + y^2) - re : rem current height
if t = int(t) then print t, int(x), int(y), int(hei), att, vx, vy
if att > pi or att < - pi/4 or hei < 0 then print "self-destroyed" : end
if m <= 10e3 then goto shutdown
gosub pilot
if stage and vm <= -800 then vm = vm / 4 : fth = fth / 4
if off then goto shutdown
goto loop
shutdown:
at1 = atn(x / y) : rem at1 is attitude of X, Y vector
if vx < vy then at2 = atn(vx / vy) : rem at2 is attitude of Vx, Vy vector
if vx >= vy then at2 = atn(vy / -vx) + pi / 2 : rem we use them to find direction error
err = at1 + pi/2 - at2
print "H:", int(hei), "V:", int(sqr(vx^2 + vy^2)), "direction error:", err * 180/pi, "degrees"
end
pilot: : example of the dummy control algorithm
if t >= 50 and t < 65 then fa = 1
if t >= 65 and t < 80 then fa = -1
if t = 80 then fa = 0
if t = 250 then stage = 1
if t = 550 then off = 1
return