# 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.

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.

## 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.

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.

Now we can plot the x position of the rocket:

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

## 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:

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.

### 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

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

[4.65186463 4.65186449 4.65186418 4.65186435]
4.651864410237118
10000
2066.438769710403

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

## 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).

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.

### 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.

6586.523340381209

### 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.

### 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.

### 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.

## 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.

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.

40

×