-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRocketPIDController.py
More file actions
73 lines (59 loc) · 2.31 KB
/
Copy pathRocketPIDController.py
File metadata and controls
73 lines (59 loc) · 2.31 KB
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
class RocketPIDController:
"""
PID controller specifically for rocket airbrakes using apogee prediction.
Uses PREDICTED apogee (not current altitude) as the process variable
Updates based on prediction error
"""
def __init__(self, rocket_sim, target_apogee, kp, ki, kd, dt=0.01):
"""
Initialize rocket PID controller.
Parameters:
-----------
rocket_sim : RocketAltitudeSimulator
The rocket simulator
target_apogee : float
Desired final altitude (m)
kp, ki, kd : float
PID gains
dt : float
Time step (s)
"""
self.rocket = rocket_sim
self.target = target_apogee
self.kp = kp
self.ki = ki
self.kd = kd
self.dt = dt
# PID state
self.integral = 0.0
self.prev_error = 0.0
def step(self):
"""
Take one control step:
1. Get current predicted apogee
2. Calculate error from target
3. Compute PID adjustment
4. Update brake position
5. Step the simulator forward
"""
# Get predicted apogee with current brake position
predicted_apogee = self.rocket.get_output()
# Error: predicted - target (positive = overshooting, negative = undershooting)
error = predicted_apogee - self.target # ← CHANGED: flipped the sign
# PID terms
self.integral += error * self.dt
derivative = (error - self.prev_error) / self.dt
# PID output (how much to CHANGE brake position)
adjustment = self.kp * error + self.ki * self.integral + self.kd * derivative
# Get current brake position and adjust it
current_brake_pos = self.rocket.brake_position
new_brake_pos = current_brake_pos + adjustment # ← CHANGED: plus instead of minus
# Clamp to valid range [0, 1]
new_brake_pos = max(0.0, min(1.0, new_brake_pos))
# Set new brake position
self.rocket.set_input(new_brake_pos)
# Step the simulation forward
self.rocket.step(self.dt)
# Update for next iteration
self.prev_error = error
return predicted_apogee, error, new_brake_pos