Python-assignment3-at-University-of-Birmingham

Assignment 3: Landing the Rocket

In this assignment you are given a uniquely designed rocket ship, represented by a Rocket object, and tasked with landing the rocket on a platform floating in the sea. The different tasks lead you through a sequence of steps designed for you to get to know your rocket and to learn how to control it.

To start please enter your student ID into the cell below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Do not alter any of the code within this cell other 
# than the value of studentID
import numpy as np
import matplotlib.pyplot as plt
# Setting global plotting settings
plt.rcParams['font.size'] = 20
plt.rcParams['axes.formatter.useoffset'] = False
from module_engine.assignment import Rocket

# Enter your student ID here
studentID =

# Your Rocket object to be used throughout this assignment
my_rocket = Rocket(studentID)

Your rocket has been generated from your student ID such that no two different IDs will ever create the same rocket. Want to see how yours looks like? Run the code in the next cell to have a look.

1
2
3
from IPython.display import HTML
html_code="<div style='display: block;text-align: center'>"+my_rocket.show()+"</div>"
HTML(html_code)

mark

Introduction

For your new assignment you have been drafted to help with the rocket development at Space-Z. The executives at Space-Z have been watching many rocket booster landings on Youtube recently and are now pushing for their engineering team to achieve vertical landings for their rockets. Your task will be to develop a first, simple feedback-control system for the horizontal thrusters to allow the rocket to land on a floating platform. However before you can do that, you will need to familiarise yourself with the provided rocket and calibrate the thrusters.

Your rocket

You can interact with your rocket by calling methods of the ‘my_rocket’ object.

Real-time interaction:

  • you can apply horizontal thrust by using the advance method: .advance(left_thrust, right_thrust) will apply left_thrust and right_thrust respectively throughout an interval which is always $1 / 60$s long. The function returns a Numpy array with three values: the first two are the x and y positions of the rocket. If the third value is not 0, the rocket has left the simulated space and has to be reset, see below.

The simulation does not continue outside of the advance method. Therefore, by calling the advance method repeatedly, you can perform, ‘step-by-step’, a flight or landing simulation.

Utility functions:

  • .reset('space'/'drop') returns your rocket to its starting position and initial conditions. The reset function can be called with the parameters space to perform tests without gravity. or drop to attempt landings on the floating platform.
  • .get_platform_pos() returns the current position of the floating platform
  • .get_flight_data() can be called after a completed simulation, it returns the data recorded during the flight in the form of a two dimensional Numpy array, with each row being an array of three values: [t, x, y]. Here x and y refer to the rocket position at a time t after the start of the flight.

Training space

A first attempt at moving our rocket around. We are putting it into ‘space’ for testing by called .reset('space') to start. Then we use while loops to call the .advance function repeatedly. Afterwards we request the flight data and plot the recorded rocket positions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
N = 0 # step counter
Nmax = 400 # maximum number of steps
thrust = 2000.0 # a random test thrust

my_rocket.reset('space')
# applying right thrust for a while
while N<Nmax:
N+=1
pos = my_rocket.advance(0.0,thrust)
# now left thrust
N=0
while N<2*Nmax:
N+=1
pos = my_rocket.advance(thrust,0.0)
# and right thrust again
N=0
while N<Nmax:
N+=1
pos = my_rocket.advance(0.0,thrust)

track = my_rocket.get_flight_data()

Now we can plot the x position of the rocket:

1
2
3
4
5
6
7
8
9
10
11
t=track[:,0]
x=track[:,1]

# Plot the x-position as a function of time
fig = plt.figure(figsize=(15,5))
ax = plt.plot(t,x, 'b-')
plt.title('rocket track')
plt.xlabel('time [s]')
plt.ylabel('x position [m]')
plt.grid()
plt.show()

mark

From the position information we can compute the velocity and acceleration as well:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Let's compute the speed and acceleration of our rocket
v = np.diff(x)/np.diff(t)
a = np.diff(v)/np.diff(t)[1:]

fig = plt.figure(figsize=(15,5))
# Plot velocity and acceleration as a function of time
plt.plot(t[1:],v, 'b-', label='velocity')
plt.plot(t[2:],a, 'r-', label='acceleration')
plt.title('rocket velocity and acceleration')
plt.xlabel('time [s]')
plt.ylabel('a.u')
plt.grid()
plt.legend()
plt.show()

mark

Calibration

From the test above we can already see that we need to calibrate the rocket thrusters: we applied some numerical value to the input arguments left_thrust and right_thrust in advance, but the result shows a different numerical value for the resulting acceleration. This means that the actual thrust is not euqal to the numerical values requested via the advance function. You can assume that the real acceleration of the rocket from the thrust requested from each thruster can be estimated by the equations:

mark

and:

  • $m$ is the mass of the rocket
  • $o$ is an offset between requested thrust and applied thrust
  • $tmax$ is a maximum level for achievable thrust

The parameter $o$ is different for each thruster and the numerical values unknown. Also, the rocket mass $m$ and the maximum for the requested thrust are unknown.

In this task you are asked to use the space mode with your rocket to calibrate your thrusters. You are supposed to do one or several experiments to find the parameters $o$ for each thruster, the mass $m$ and the maximum thrust $tmax$. This is another example for the process of system identification, however, this time we should not use the frequency domain but use the time domain data directly.

Task 1: System Identification

Marks available: 8

Interact with your rocket in order to obtain the numerical values for $o$ (left and right), $tmax$ and $m$ with the following accuracy:

  • m, rocket mass, +- 1.0 kg
  • o_left, o_right, thrust offset, +- 1 N
  • tmax, maximum thrust, +- 10.0 N
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# Student code to experiment with rocket
# First tests: calculate thrust offsets

Nmax = 5 # maximum number of steps
thrust = 10000.0 # start piont of thrust test

def get_a(thrust):
N = 0 # step counter
my_rocket.reset('space')
# applying right thrust for a while
while N<Nmax:
N+=1
pos = my_rocket.advance(0.0,thrust)

track = my_rocket.get_flight_data()

t=track[:,0]
x=track[:,1]

# Let's compute the speed and acceleration of our rocket
v = np.diff(x)/np.diff(t)
a = np.diff(v)/np.diff(t)[1:]

return a

def get_a_left(thrust):
N = 0 # step counter
my_rocket.reset('space')
# applying right thrust for a while
while N<Nmax:
N+=1
pos = my_rocket.advance(thrust,0.0)

track = my_rocket.get_flight_data()

t=track[:,0]
x=track[:,1]

# Let's compute the speed and acceleration of our rocket
v = np.diff(x)/np.diff(t)
a = np.diff(v)/np.diff(t)[1:]

return a

# right thrust

# print(get_a(250))
# print(get_a(500))

# bisection
low_thrust = 250
high_thrust = 500

while (high_thrust-low_thrust)>1 and abs(get_a(low_thrust)[0])<abs(get_a(high_thrust)[0]):
mid_thrust = (low_thrust + high_thrust)/2
print(mid_thrust)
if abs(get_a(mid_thrust)[0])==0 and abs(get_a(low_thrust)[0])==0:
low_thrust = mid_thrust
elif abs(get_a(mid_thrust)[0])>0:
high_thrust = mid_thrust
else:
print("error")
exit()

print(get_a(low_thrust))
print(get_a(high_thrust))
print((low_thrust+high_thrust)/2)

# left thrust

print()
print(get_a_left(500))
print(get_a_left(750))

# bisection
low_thrust = 500
high_thrust = 750

while (high_thrust-low_thrust)>1 and abs(get_a_left(low_thrust)[0])<abs(get_a_left(high_thrust)[0]):
mid_thrust = (low_thrust + high_thrust)/2
print(mid_thrust)
if abs(get_a_left(mid_thrust)[0])==0 and abs(get_a_left(low_thrust)[0])==0:
low_thrust = mid_thrust
elif abs(get_a_left(mid_thrust)[0])>0:
high_thrust = mid_thrust
else:
print("error")
exit()

print(get_a_left(low_thrust))
print(get_a_left(high_thrust))
print((low_thrust+high_thrust)/2)

375.0
437.5
406.25
390.625
382.8125
386.71875
388.671875
387.6953125
[0. 0. 0. 0.]
[-0.00016308 -0.00016272 -0.00016344 -0.00016272]
387.20703125

[0. 0. 0. 0.]
[0.00850644 0.00850572 0.00850644 0.00850608]
625.0
687.5
718.75
734.375
726.5625
730.46875
732.421875
733.3984375
[0. 0. 0. 0.]
[0.00047232 0.00047232 0.0004716 0.00047268]
732.91015625

1
2
3
4
5
6
7
8
# Second experiment: calculate mass

F = 10000
a = -get_a(F)
print(a)
print(a.mean())
print(F)
print((F-387.20703125)/a.mean()) # BE CAREFUL HERE

[4.65186463 4.65186449 4.65186418 4.65186435]
4.651864410237118
10000
2066.438769710403

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# Last experiment: get maximum thrust

Nmax = 5 # maximum number of steps
thrust = 10000.0 # start piont of thrust test

# right thrust

# print(get_a(250))
# print(get_a(500))

# print(get_a(5000))
# print(get_a(10000))
# print(get_a(12500))
# print(get_a(15000))

# bisection
low_thrust = 10000
high_thrust = 12500

while (high_thrust-low_thrust)>1 and abs(get_a(low_thrust)[0])<abs(get_a(high_thrust)[0]):
mid_thrust = (low_thrust + high_thrust)/2
print(mid_thrust)
if abs(get_a(mid_thrust)[0])<abs(get_a(high_thrust)[0]):
low_thrust = mid_thrust
elif abs(get_a(mid_thrust)[0]) == abs(get_a(high_thrust)[0]):
high_thrust = mid_thrust
else:
print("error")
exit()

print(get_a(low_thrust))
print(get_a(high_thrust))
print((low_thrust+high_thrust)/2)
print((low_thrust+high_thrust)/2 - 387.2)

# left thrust

print()
# print(get_a_left(5000))
# print(get_a_left(10000))
# print(get_a_left(12500))
# print(get_a_left(15000))

# bisection
low_thrust = 10000
high_thrust = 12500

while (high_thrust-low_thrust)>1 and abs(get_a_left(low_thrust)[0])<abs(get_a_left(high_thrust)[0]):
mid_thrust = (low_thrust + high_thrust)/2
print(mid_thrust)
if abs(get_a_left(mid_thrust)[0])<abs(get_a_left(high_thrust)[0]):
low_thrust = mid_thrust
elif abs(get_a_left(mid_thrust)[0]) == abs(get_a_left(high_thrust)[0]):
high_thrust = mid_thrust
else:
print("error")
exit()

print(get_a_left(low_thrust))
print(get_a_left(high_thrust))
print((low_thrust+high_thrust)/2)
print((low_thrust+high_thrust)/2 - 732.9)

11250.0
10625.0
10937.5
10781.25
10703.125
10742.1875
10722.65625
10712.890625
10708.0078125
10710.44921875
10709.228515625
10709.8388671875
[-4.99537843 -4.99537756 -4.99537834 -4.99537816]
[-4.99565203 -4.99565224 -4.99565194 -4.99565248]
10710.14404296875
10322.94404296875

11250.0
10625.0
10937.5
11093.75
11015.625
11054.6875
11074.21875
11064.453125
11059.5703125
11057.12890625
11055.908203125
11055.2978515625
[4.99556887 4.99556872 4.9955695 4.9955686 ]
[4.99565203 4.99565224 4.99565194 4.99565248]
11055.60302734375
10322.70302734375

1
2
3
4
5
6
7
# Enter the results from your experiments into these variables here
# (you may type the numerical value with the requested accuracy or you
# can assign these variables to another variable computed above):
o_left = 732.91015625
o_right = 387.20703125
m = 2066.438769710403
tmax = 10322.8

Task 2: There and Stop

Marks available: 2

Knowing the thruster calibration, we can try to move the rocket around in a more precise fashion. In this task you must move a rocket from the starting point x0 to a point x1.

Using the thruster calibration

First write two utility functions that make use of the known thruster calibration to compute the required thrust for a given acceleration that we want to apply to the rocket. Each function should accept a Numpy array and return a Numpy array (both of float values).

1
2
3
4
5
6
7
8
9
10
11
12
13
# Add functions here (do not change the function names!)

def acc2thrust_left(acceleration):
# your code here
thrust = m*acceleration
thrust += o_left
return thrust

def acc2thrust_right(acceleration):
# your code here
thrust = m*acceleration
thrust += o_right
return thrust

You should test these functions by applying a known acceleration to the rocket and compare it to the measured acceleration. This test will not be marked, but it is your only means for testing if your functions work as required. You will lose marks in this and the following tasks if the functions are not implemented exactly as requested. Hint: after doing an experiment that uses your utility functions make a plot that shows the difference between the requested and the measured acceleration. For thrusts below the maximum value the absolute acceleration errors should be well below 1/1000.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Test thruster utility functions
N = 0 # step counter
Nmax = 400 # maximum number of steps


my_rocket.reset('space')
# applying right thrust for a while
while N<Nmax:
N+=1
pos = my_rocket.advance(0.0,thrust)

track = my_rocket.get_flight_data()
t=track[:,0]
x=track[:,1]

# Plot the x-position as a function of time
fig = plt.figure(figsize=(15,5))
ax = plt.plot(t,x, 'b-')
plt.title('rocket track')
plt.xlabel('time [s]')
plt.ylabel('x position [m]')
plt.grid()
plt.show()

# Let's compute the speed and acceleration of our rocket
v = np.diff(x)/np.diff(t)
a = np.diff(v)/np.diff(t)[1:]

fig = plt.figure(figsize=(15,5))
# Plot velocity and acceleration as a function of time
plt.plot(t[1:],v, 'b-', label='velocity')
plt.plot(t[2:],a, 'r-', label='acceleration')
plt.title('rocket velocity and acceleration')
plt.xlabel('time [s]')
plt.ylabel('a.u')
plt.grid()
plt.legend()
plt.show()

fig = plt.figure(figsize=(15,5))
# Plot acceleration difference as a function of time
plt.plot(t[2:],3+a, 'r-', label='acceleration error')
plt.title('rocket acceleration error range')
plt.xlabel('time [s]')
plt.ylabel('a')
plt.grid()
plt.legend()
plt.show()

mark
mark
mark

Moving the rocket with a pre-calculated control sequence

Now make use of your utility functions to move the
rocket exactly 100 meters to the right such that it stops there. Your starting point is x0, and the target point at which you should stop is x1=x0+100m. The task is to

  • end the flight with the rocket speed $v<0.1$m/s
  • at a position $x=x1\pm 1$m.
  • The total flight time must be less than 30s.
  • at no time the rocket position must be larger than x = x0 + 101m

You are not supposed to use any algorithm to determine your rocket thrust in real time, but to use a constant thrust (left or right) for pre-determined lengths of time. In other words, you hard-code a control sequence in advance of the flight. Note that you must fire the left thruster to move to the right.

The marking script will evaluate your track data, recorded in the cell below the next. Make sure that the track data contains the full flight path. You should plot your track to check at least that you arrived at the correct final position in the allowed time.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Student code for 'there and stop'

N = 0 # step counter
Nmax = 600 # maximum number of steps
thrust_l = acc2thrust_left(1)
thrust_r = acc2thrust_right(1)
print(thrust)

my_rocket.reset('space')
# applying left thrust for a while
while N<Nmax:
N+=1
pos = my_rocket.advance(thrust_l,0.0)
N = 0
# applying right thrust for a while
while N<Nmax:
N+=1
pos = my_rocket.advance(0.0,thrust_r)

6586.523340381209

1
2
3
# The following records the track data to be marked, Make sure
# that you do not call `reset()` during or after your flight!
student_track1 = my_rocket.get_flight_data()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Cell for plotting the track to check results

track = my_rocket.get_flight_data()
t=track[:,0]
x=track[:,1]

# Plot the x-position as a function of time
fig = plt.figure(figsize=(15,5))
ax = plt.plot(t,x, 'b-')
plt.title('rocket track')
plt.xlabel('time [s]')
plt.ylabel('x position [m]')
plt.grid()
plt.show()

# Let's compute the speed and acceleration of our rocket
v = np.diff(x)/np.diff(t)
a = np.diff(v)/np.diff(t)[1:]

fig = plt.figure(figsize=(15,5))
# Plot velocity and acceleration as a function of time
plt.plot(t[1:],v, 'b-', label='velocity')
plt.plot(t[2:],a, 'r-', label='acceleration')
plt.title('rocket velocity and acceleration')
plt.xlabel('time [s]')
plt.ylabel('a.u')
plt.grid()
plt.legend()
plt.show()

mark
mark

Task 3: Feedback Control

Marks available: 6

In the task above we could use our accurate knowledge of the total force acting on the rocket to determine the required thrust for the entire flight in advance. However, in the final task when we want to land the rocket, side winds and a moving target will make this approach impossible. Instead we must use a feedback control system.

Feedback control makes use of real-time information to change parameters. In our case we will use the horizontal position of the rocket to adjust the applied thrust. In this task you will develop a feedback algorithm for your rocket.

Moving there, using feedback

Your task is again to move the rocket from a starting point $x0$ to a new target position $x=x0+100$ m and keep it there, but now using a feedback system.

The first naive approach is to fire the left thruster if the rocket is to the left of the target, and fire the right thruster when it is to the right of the target. We might be already a bit smarter and compute the thrust such that it is proportional to the distance of the rocket from the target. However, this will not work, instead the rocket will oscillate around the target position. Nevertheless, you will first implement such a not successful algorithm to verify this.

Write a function that accepts 2 input arguments: the x-position of the rocket and the target position, and returns two values: left_thrust and right_thrust to be used with advance() method. Your function should compute the thrust such that the rocket acceleration is proportional to the distance from the target, using a code similar to acc = gain * (target-pos). The gain is a numerical scaling that you can set to change the strength of the feedback. Your function should call the acc2thrust_right and acc2thrust_left functions defined above.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Student code for position-based feedback,
# do *not* change the name or arguments of the function.

def position_feedback(pos, target):

# Your code here

gain = 200
acc = (target - pos)*gain
left_thrust = 0
right_thrust = 0

if acc > 0:
left_thrust = acc2thrust_left(acc)
elif acc < 0:
right_thrust = acc2thrust_right(-acc)
else:
left_thrust = 0
right_thrust = 0

return left_thrust, right_thrust

Oscillate

Test your function by trying to move the rocket to a target position which is 100 m to the right of your starting position. Adjust the gain in your function such that you can clearly see the rocket oscillation around the target position during an approximately 60 s long flight. The track of your test is recorded in the cell below next. Your track data stored in ‘student_track2’ will be analysed and marked.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Student code for creating flight path with 
# an oscillation around target

my_rocket.reset("space")

#Your code here
N = 0 # step counter
Nmax = 3600 # maximum number of steps
#thrust_l,thrust_r = position_feedback(pos[0], 100)
#print(thrust_l,thrust_r)

my_rocket.reset('space')
pos = my_rocket.advance(0.0, 0.0)
# applying left thrust for a while
while N<Nmax:
N+=1
thrust_l,thrust_r = position_feedback(pos[0], 100)
if thrust_l == 0 and thrust_r == 0:
pos = my_rocket.advance(0.0,0.0)
elif thrust_l == 0:
pos = my_rocket.advance(0.0,thrust_r)
elif thrust_r == 0:
pos = my_rocket.advance(thrust_l,0.0)
1
2
3
# The following records the track data to be marked, Make sure
# that you do not call `reset()` during or after your flight!
student_track2 = my_rocket.get_flight_data()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Cell for plotting the track to check results

track = my_rocket.get_flight_data()
t=track[:,0]
x=track[:,1]

# Plot the x-position as a function of time
fig = plt.figure(figsize=(15,5))
ax = plt.plot(t,x, 'b-')
plt.title('rocket track')
plt.xlabel('time [s]')
plt.ylabel('x position [m]')
plt.grid()
plt.show()

# Let's compute the speed and acceleration of our rocket
v = np.diff(x)/np.diff(t)
a = np.diff(v)/np.diff(t)[1:]

fig = plt.figure(figsize=(15,5))
# Plot velocity and acceleration as a function of time
plt.plot(t[1:],v, 'b-', label='velocity')
plt.plot(t[2:],a, 'r-', label='acceleration')
plt.title('rocket velocity and acceleration')
plt.xlabel('time [s]')
plt.ylabel('a.u')
plt.grid()
plt.legend()
plt.show()

mark
mark

Damped Oscillation

The above result should not be surprising: we have created a system in which a restoring force is proportional to the position. Therefore we have created a harmonic oscillator that will oscillate forever around the target position. What we want to do instead is to create a damped oscillator that settles (quickly) at the target. We can achieve that by using a new function that computes the feedback based on the position and speed of the rocket.

Write a new feedback function to compute the rocket thrust. The function should accept three input arguments, position, velocity and target position. Internally it should use two gain values, a position gain pos_gain and a velocity gain v_gain, and return the thrust values as before.

Adjust the two gains such that the rocket reaches its target quickly and does not overshoot the target by more than $1$m at any time. Perform a flight and record the track data in the cells below. The variable ‘student_track3’ will be used for marking your work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Student code for position and velocity feedback,
# do *not* change the name or arguments of the function.

def damped_feedback(pos, v, target): # v is absolute value

# Your code here

pos_gain = 1200
v_gain = 3000

if pos < target:
left_thrust, right_thrust = pos_gain * (target - pos) - v_gain * v, 0
if left_thrust < 0:
left_thrust, right_thrust = right_thrust, -left_thrust
else:
right_thrust, left_thrust = pos_gain * (pos - target) + v_gain * v, 0
if right_thrust < 0:
left_thrust, right_thrust = -right_thrust, left_thrust
return left_thrust, right_thrust
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Student code to create flight track with damped oscillation

my_rocket.reset("space")
#Your code here

target = 100
pos = 0
v = 0
thrust = damped_feedback(pos,v, target)
my_rocket.advance(*thrust)
pos = my_rocket.rocket_pos[0]
v = my_rocket.rocket_velocity[0]
for i in range(100 * 60 // 2):
thrust = damped_feedback(pos,v, target)
my_rocket.advance(*thrust)
pos = my_rocket.rocket_pos[0]
v = my_rocket.rocket_velocity[0]
1
2
3
# The following records the track data to be marked, Make sure
# that you do not call `reset()` during or after your flight!
student_track3 = my_rocket.get_flight_data()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Cell for plotting the track to check results

track = my_rocket.get_flight_data()
t=track[:,0]
x=track[:,1]

# Plot the x-position as a function of time
fig = plt.figure(figsize=(15,5))
ax = plt.plot(t,x, 'b-')
plt.title('rocket track')
plt.xlabel('time [s]')
plt.ylabel('x position [m]')
plt.grid()
plt.show()

# Let's compute the speed and acceleration of our rocket
v = np.diff(x)/np.diff(t)
a = np.diff(v)/np.diff(t)[1:]

fig = plt.figure(figsize=(15,5))
# Plot velocity and acceleration as a function of time
plt.plot(t[1:],v, 'b-', label='velocity')
plt.plot(t[2:],a, 'r-', label='acceleration')
plt.title('rocket velocity and acceleration')
plt.xlabel('time [s]')
plt.ylabel('a.u')
plt.grid()
plt.legend()
plt.show()

mark
mark

Task 4: Landing the Rocket

Marks available: 4

We have finally arrived at the real challenge: your rocket starts at $2000$m above the sea level and your goal is to land it on a $20$m floating platform in the sea.

The platform will change location between each run (upon calling .reset('drop')) and might also float sideways during your rocket’s descent. You can get the coordinates of the platform’s centre at any time using my_rocket.get_platform_pos(). These coordinates should be your target (a landing will be deemed successful if it is within $\pm 10$m of it).

The rocket will be accelerated by gravity. In addition, it will be subject to atmospheric drag, which lessens the downwards acceleration a bit, but more importantly, any side wind will result in unpredictable horizontal forces. However you are already well equipped with the feedback control system from the previous task, which should handle wind and moving targets without any further adjustments.

In this task you must switch the rocket to landing mode by always using reset('drop').

Write a loop to attempt 40 landings, the number of successful landings will be recorded automatically. Note that you might not be able to succeed in 100% of your attempts. You can achieve full marks by landing 70% of your rockets successfully.

At the start of the next cell you may call my_rocket.reset_flight_counter() to start counting flights from the 0 before looping over the 40 test landings. Make sure that you use the variable ‘tracks’ to store all your flight paths (as prepared in the while-loop below), because this variable will be used for marking.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# Student code to land rocket

my_rocket.reset_flight_counter()
Nflights=40
N=0
tracks=[]
# Your code here

while N<Nflights:
my_rocket.reset('drop')
# Your code here
target = my_rocket.get_platform_pos()[0]
pos = my_rocket.rocket_pos[0]
print('pos:{}'.format(pos),end=' ')
v = 0
thrust = damped_feedback(pos,v, target)
my_rocket.advance(*thrust)
pos = my_rocket.rocket_pos[0]
v = my_rocket.rocket_velocity[0]
for i in range(20 * 60 ):
thrust = damped_feedback(pos,v, target)
my_rocket.advance(*thrust)
pos = my_rocket.rocket_pos[0]
v = my_rocket.rocket_velocity[0]

tracks.append(my_rocket.get_flight_data())
N+=1

pos:100.0 The rocket lands on the platform.
1 / 1 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
2 / 2 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
3 / 3 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
4 / 4 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
5 / 5 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
6 / 6 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
7 / 7 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
8 / 8 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
9 / 9 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
10 / 10 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
11 / 11 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
12 / 12 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
13 / 13 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
14 / 14 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
15 / 15 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
16 / 16 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
17 / 17 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
18 / 18 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
19 / 19 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
20 / 20 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
21 / 21 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
22 / 22 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
23 / 23 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
24 / 24 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
25 / 25 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
26 / 26 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
27 / 27 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
28 / 28 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
29 / 29 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
30 / 30 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
31 / 31 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
32 / 32 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
33 / 33 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
34 / 34 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
35 / 35 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
36 / 36 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
37 / 37 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
38 / 38 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
39 / 39 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

pos:100.0 The rocket lands on the platform.
40 / 40 flights have resulted in a successful landing.
Call .reset(“drop”) before attempting a new flight.

1
2
3
4
5
6
7
8
9
10
11
12
13
# Student code to plot flight paths 
fig = plt.figure(figsize=(15,5))
for track in tracks:
t=track[:,0]
x=track[:,1]
# Plot the x-position as a function of time
plt.plot(t,x, '-')
plt.title('rocket track')
plt.xlabel('time [s]')
plt.ylabel('x position [m]')
plt.grid()
plt.show()
print('there are 40 flight paths.')

mark

1
2
# Check how many flights succeeded:
print(my_rocket.successful_landing_counter)

40

×

纯属好玩

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

文章目录
  1. 1. Assignment 3: Landing the Rocket
    1. 1.1. Introduction
      1. 1.1.1. Your rocket
    2. 1.2. Training space
    3. 1.3. Calibration
    4. 1.4. Task 1: System Identification
      1. 1.4.1. Marks available: 8
    5. 1.5. Task 2: There and Stop
      1. 1.5.1. Marks available: 2
      2. 1.5.2. Using the thruster calibration
      3. 1.5.3. Moving the rocket with a pre-calculated control sequence
    6. 1.6. Task 3: Feedback Control
      1. 1.6.1. Marks available: 6
      2. 1.6.2. Moving there, using feedback
      3. 1.6.3. Oscillate
      4. 1.6.4. Damped Oscillation
    7. 1.7. Task 4: Landing the Rocket
      1. 1.7.1. Marks available: 4