-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathicarus_sim.html
More file actions
211 lines (190 loc) · 9.78 KB
/
Copy pathicarus_sim.html
File metadata and controls
211 lines (190 loc) · 9.78 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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Icarus Flight Simulations | Brandon Jacobson</title>
<meta name="description" content="Project Icarus simulation work — from 1D PID altitude control to full 6-DoF quadrotor simulation with Kalman filter state estimation." />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- ── Navigation ── -->
<nav class="site-nav">
<div class="nav-inner">
<a href="index.html" class="nav-logo">Brandon Jacobson</a>
<button class="nav-toggle-btn" aria-label="Toggle menu" onclick="
document.querySelector('.nav-links').classList.toggle('open')
">☰</button>
<div class="nav-links">
<a href="index.html" class="nav-desktop">Home</a>
<a href="projects.html" class="nav-desktop">Projects</a>
<a href="https://github.com/brandonjacobson" target="_blank" rel="noreferrer" class="nav-desktop">GitHub</a>
<a href="https://www.linkedin.com/in/b-jacobson" target="_blank" rel="noreferrer" class="nav-desktop">LinkedIn</a>
<a href="Resume.pdf" target="_blank" rel="noreferrer" class="nav-resume">Resume</a>
</div>
</div>
</nav>
<main>
<div class="page-container">
<div class="breadcrumbs">
<a href="index.html">Home</a>
<span>/</span>
<a href="projects.html">Projects</a>
<span>/</span>
<span>Icarus Simulations</span>
</div>
<!-- ── Page Hero ── -->
<div class="project-page-hero">
<h1 class="project-page-title">Project Icarus — Flight Simulations</h1>
<p class="project-page-subtitle">
Simulation work for Project Icarus, progressing from 1D PID altitude control
to a full 6-DoF quadrotor simulation with Kalman filter state estimation and
closed-loop trajectory tracking.
</p>
<div class="badge-row">
<span class="badge">Python · NumPy · Matplotlib</span>
<span class="badge">6-DoF Dynamics</span>
<span class="badge">Kalman Filter</span>
<span class="badge">PID Control</span>
</div>
</div>
<!-- ════════════════════════════════════
BLOCK 1 — Kalman Filter Update
════════════════════════════════════ -->
<div class="sim-block" id="kf-simulation">
<div class="sim-block-header">
<h2 class="sim-block-title">6-DoF Simulation with Kalman Filter State Estimation</h2>
<span class="sim-block-label">Latest</span>
</div>
<!-- Simulation GIF -->
<div class="sim-gif-wrap">
<img
src="images/KF/drone_trajectory.gif"
alt="6-DoF quadrotor simulation animating trajectory tracking through step waypoints"
loading="eager"
/>
<p class="sim-gif-caption">
6-DoF quadrotor simulation — Kalman-filtered state estimates drive
closed-loop PID control through a sequence of step waypoints.
</p>
</div>
<!-- Key Highlights + Stack -->
<div class="two-column" style="margin-bottom: var(--sp-8)">
<div>
<h3 style="font-size:0.95rem;font-weight:700;margin-bottom:var(--sp-3);color:var(--text)">Key Highlights</h3>
<ul style="font-size:0.92rem;line-height:1.8;color:var(--text-muted)">
<li>KF estimate converges to true position despite scattered GPS measurements.</li>
<li>Closed-loop controller tracks step waypoints across X, Y, and Z simultaneously.</li>
<li>Attitude remains stable through position transitions (<30° max tilt).</li>
<li>All four motor RPMs converge to steady-state hover after each waypoint.</li>
</ul>
</div>
<div>
<h3 style="font-size:0.95rem;font-weight:700;margin-bottom:var(--sp-3);color:var(--text)">Stack</h3>
<ul style="font-size:0.92rem;line-height:1.8;color:var(--text-muted)">
<li><strong>Language:</strong> Python, NumPy, Matplotlib</li>
<li><strong>Dynamics:</strong> Nonlinear 6-DoF quadrotor model</li>
<li><strong>Estimator:</strong> 6-state Kalman filter (position + velocity)</li>
<li><strong>Attitude:</strong> Complementary filter on simulated IMU</li>
<li><strong>Control:</strong> Cascade PID — position loop + attitude loop</li>
</ul>
</div>
</div>
<!-- Plots -->
<div class="plot-grid">
<div class="plot-card">
<div class="plot-card-img">
<img
src="images/KF/KF_Position_Estimation_Success_3_9_26.png"
alt="Kalman filter position estimation: true position vs. KF estimate vs. noisy GPS across X, Y, and Z axes"
loading="lazy"
/>
</div>
<div class="plot-card-caption">
<strong>Kalman Filter — True vs. Estimated vs. GPS</strong>
<p>
KF estimate (red) tracks true position (blue) closely despite scattered GPS
readings (green ×). Altimeter data (orange) fuses with GPS for Z-axis estimation.
</p>
</div>
</div>
<div class="plot-card">
<div class="plot-card-img">
<img
src="images/KF/KF_Success_Position_Attitude_Motors_3_9_26.png"
alt="Full system telemetry: position tracking, Euler attitude angles, and four motor RPMs over 30 seconds"
loading="lazy"
/>
</div>
<div class="plot-card-caption">
<strong>Full Telemetry — Position, Attitude & Motors</strong>
<p>
X/Y/Z position tracks step waypoints (dashed) with clean transient response.
Euler angles settle to near-zero in hover. All four motor RPMs converge
after each commanded waypoint.
</p>
</div>
</div>
</div>
</div>
<!-- ════════════════════════════════════
BLOCK 2 — 1D Simulation
════════════════════════════════════ -->
<div class="sim-block" id="1d-simulation">
<div class="sim-block-header">
<h2 class="sim-block-title">1D Vertical Flight Simulation</h2>
<span class="sim-block-label label-muted">Earlier Work</span>
</div>
<p style="font-size:0.95rem;color:var(--text-muted);line-height:1.8;margin-bottom:var(--sp-6)">
The starting point for Icarus simulation — a 1D vertical flight model with PID altitude
control, sensor noise, and low-pass filtering used to validate the control approach
before extending to 6-DoF.
</p>
<div class="gallery" style="margin-bottom: var(--sp-8)">
<figure class="media-card">
<img src="images/Vertical_Thrust_Test1_Plot.png" alt="Baseline autonomous 10 m hover simulation plot" />
<figcaption>Baseline autonomous 10 m hover test — altitude and thrust vs. time.</figcaption>
</figure>
<figure class="media-card">
<img src="images/NoisyTest1.png" alt="Noisy thrust response under PID control" />
<img src="images/NoisyTest1_RPM.png" alt="Noisy RPM response under PID control" />
<figcaption>Noisy thrust and RPM response under PID control during 10 m hover.</figcaption>
</figure>
<figure class="media-card">
<img src="images/LowPassTest1.png" alt="Low-pass filtered thrust signal" />
<figcaption>Low-pass filtered thrust signal showing smoother control despite noise.</figcaption>
</figure>
</div>
<div class="two-column">
<div>
<h3 style="font-size:0.95rem;font-weight:700;margin-bottom:var(--sp-3);color:var(--text)">Key Highlights</h3>
<ul style="font-size:0.92rem;line-height:1.8;color:var(--text-muted)">
<li>Modeled three-phase flight profile: ground → 10 m hover → soft landing.</li>
<li>Simulated noisy thrust and RPM measurements to evaluate controller robustness.</li>
<li>Applied low-pass filtering to reduce thrust oscillations under sensor noise.</li>
</ul>
</div>
<div>
<h3 style="font-size:0.95rem;font-weight:700;margin-bottom:var(--sp-3);color:var(--text)">Stack</h3>
<ul style="font-size:0.92rem;line-height:1.8;color:var(--text-muted)">
<li><strong>Language:</strong> Python, NumPy, Matplotlib</li>
<li><strong>Control:</strong> PID altitude control</li>
<li><strong>Modeling:</strong> 1D thrust dynamics, noisy sensor measurements</li>
<li><strong>Signal Processing:</strong> Low-pass filter on thrust commands</li>
</ul>
</div>
</div>
</div>
<!-- ── Links ── -->
<div style="display:flex;gap:var(--sp-3);flex-wrap:wrap;padding-bottom:var(--sp-4)">
<a href="https://github.com/brandonjacobson/Project-Icarus" class="btn btn-primary" target="_blank" rel="noreferrer">View Code on GitHub</a>
<a href="icarus.html" class="btn btn-outline">Hardware Platform</a>
</div>
</div><!-- /.page-container -->
</main>
<footer class="site-footer">
<p>© 2025 Brandon Jacobson</p>
<p><a href="mailto:brandonjacobson0@gmail.com">brandonjacobson0@gmail.com</a></p>
</footer>
</body>
</html>