Oleh
Rizqy Agung (23621018)
Solusi No. 1
Sebelum membuat program pada python, beberapa modul perlu diimpor untuk menyediakan
beberapa fungsi untuk perhitungan matematika.
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import pandas as pd
df = pd.read_csv("doublet.csv")
df
Lalu output dari code tersebut menunjukkan bahwa terdapat 201 baris dan 2 kolom dari data
berbentuk doublet tersebut
Apabila dibuat kedalam bentuk program, maka akan tervisualisasikan seperti berikut
uinput = pd.read_csv('doublet.csv')
plt.figure(figsize=(8,4))
plt.plot(uinput.time_s, uinput.doublet)
_ = plt.xlim(0, 20)
_ = plt.xlabel('time (s)', fontsize=12)
_ = plt.ylabel('input', fontsize=12)
Pemodelan persamaan state-space seperti yang diketahui dari soal, dimodelkan diprogramkan
dalam python seperti berikut
Implementasi dari mencari solusi persamaan state-space tersebut dengan Metode Euler,
diprogram dengan code berikut ini
Program code dan hasil visualisasi plot dari respon sistem dengan metode ini adalah
fig, ax = plt.subplots(1,2, figsize=(15, 4))
for i, axes in enumerate(ax):
axes.grid(ls='--', lw=0.5, color='black')
axes.plot(uinput.time_s, x_eu[:, i], lw=2.5, c='red')
axes.set_xlabel('time (s)', fontsize=18)
axes.set_ylabel(f'$x_{i+1}$', fontsize=18)
axes.set_xlim(0, 20)
Implementasi metode Runge-kutta orde ke-4 pada data yang inisialisasi dilakukan juga
dengan mengintegrasikan hasil setiap iterasi (dengan for loop)
Program dan visualisasi hasil plot respon sistem dengan Metode Runge-Kutta orde-4
disajikan pada code dan gambar berikut
fig, ax = plt.subplots(1,2, figsize=(15, 4))
for i, axes in enumerate(ax):
axes.grid(ls='--', lw=0.5, color='black')
axes.plot(uinput.time_s, x_rk[:, i], lw=2.5, c='k')
axes.set_xlabel('time (s)', fontsize=18)
axes.set_ylabel(f'$x_{i+1}$', fontsize=18)
axes.set_xlim(0, 20)
Gambar 3. Plot Respon Sistem Dinamik dengan Metode Runge-Kutta orde ke-4
Selain itu, saya juga melalukan perbandingan antara metode Euler dan Runge-Kutta orde ke-4
Inisiasi data parameter, variabel, serta interval waktu yang akan digunakan dibuat seperti
berikut ini
Implementasi dan visualisasi respon sistem dengan Metode Diskritisasi dibuat dan disajikan
pada code dan gambar berikut
Gambar 6. Plot Respon Sistem Dinamik dengan Metode Diskritisasi dengan interval waktu 1 detik
Gambar 7. Plot Respon Sistem Dinamik dengan Metode Diskritisasi pada dua interval waktu yang berbeda
Dapat dilihat dari kedua plot di atas, bahwa interval waktu pada Metode Diskritisasi sangat
memengaruhi hasil dari solusi yang didapatkan (semakin kecil intervalnya, maka hasilnya akan
lebih baik). Namun tentunya dibutuhkan kebijaksanaan dalam memilih interval waktu yang
digunakan, agar kerja komputer tidak terlalu berat dan hasil yang didapat sudah cukup akurat.
d. Perbandingan antara ketiga metode diatas, diimplementasikan dengan program
seperti berikut ini
Dapat diobservasi dan dianalisa bahwa berdasarkan Gambar 8 diatas terlihat bahwa dengan
Metode Runge-Kutta orde ke-4 dan Metode Diskritisasi dengan dt = 0.1 menunjukan plot yang
hampir berdempetan. Hal ini menunjukkan bahwa, tingkat keakuratan kedua metode ini lebih
baik daripada dengan Metode Euler (merupakan metode yang sederhana). Dimana pada
Metode Runge-Kutta orde ke 4, terdapat 4 kali “Evaluation Function” yang didalamnya juga
terdapat faktor nilai tengah dari interval waktu tersebut. Artinya, metode ini selalu berusaha
untuk meminimkan nilai error dari mencari nilai tengah dari setiap hasil evaluasi fungsinya.
Sementara itu, Metode Diskritisasi yang berbasis integral tersebut menghasilkan respon sistem
yang mirip dengan Runge-Kutta. Hal ini dikarenakan interval waktu yang cukup sempit,
sehingga hasil integrasinya juga tidak akan memberikan error yang terlalu signifikan.
No. 2
Simulasi attitude propagation model dengan Metode Runge-Kutta orde ke-4. Persamaan yang
akan digunakan adalah
𝜙̇ = 𝑝 + 𝑡𝑎𝑛𝜃(𝑞. 𝑠𝑖𝑛𝜙 + 𝑟. 𝜙)
𝜃̇ = 𝑞. 𝑐𝑜𝑠𝜙 − 𝑟. 𝜙
𝑞. 𝑠𝑖𝑛𝜙̇ + 𝑟. 𝑐𝑜𝑠𝜙
𝜓=
𝑐𝑜𝑠𝜃
Dimana kondisi awalnya adalah
𝜙0 0.9𝑜
[ 𝜃0 ] = [1.7𝑜 ]
𝜓0 13𝑜
Dan interval waktu yang digunakan adalah 0.4 detik (dt = 0.4 s)
Solusi No.2
Seperti biasa, sebelum membuat program yang didalamnya terdapat fungsi matematika,
beberapa modul perlu diimpor agar fungsi matematikanya dapat digunakan
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import pandas as pd
Baca data yang diberikan untuk mengecek bentuk data, dimana data gerakan dari wahana telah
tersimpan dalam file .csv yang diberikan
uinput = pd.read_csv('pqr_input.csv')
uinput
plt.plot(uinput["p_radps"],lw=2,color='r')
plt.plot(uinput["q_radps"],lw=2,color='b')
plt.plot(uinput["r_radps"],lw=2,color='g')
plt.ylabel('radps')
plt.title("PQR Input Model")
plt.grid(ls="--",lw=0.5,color="black")
plt.legend(['p','q','r'])
plt.xlim(0,len(uinput))
plt.show()
Gambar 10. Plot Data p,q, dan r pada selang waktu tertentu
Berdasarkan persamaan matematika yang telah dijelaskan pada soal, maka code pemrograman
untuk mendefenisikan persamaannya dibuat seperti berikut ini
from numpy import float64, cos, sin, tan
def state_model(xstate,u):
p = u[0]
q = u[1]
r = u[2]
phi = xstate[0]
theta = xstate[1]
phi_dot = p + tan(theta)*(q*sin(phi)+r*phi)
theta_dot = q*cos(phi) - r*phi
psi_dot = (q*sin(phi)+r*cos(phi))/cos(theta)
xdot = [phi_dot,theta_dot,psi_dot]
return np.reshape(np.array(xdot),(-1,1))
Dengan menggunakan Metode Runge-Kutta orde ke-4 yang tadi, proses yang kurang lebih
sama dituliskan pada program. Namun perbedaannya terletak pada setiap fungsi dikalikan dt
agar propagasi sikap wahananya diiterasi terhadap waktu.
def runge_kutta(statemodel,xstate,dt,u1,u2):
k1 = dt*statemodel(xstate,u1)
k2 = dt*statemodel(xstate+k1*dt/2,(u1+u2)/2)
k3 = dt*statemodel(xstate+k2*dt/2,(u1+u2)/2)
k4 = dt*statemodel(xstate+k3*dt,(u1+u2)/2)
k = (k1+2*k2+2*k3+k4)/6
return xstate + k
Inisialisasi data untuk kasus ini dibuat dengan program berikut ini
dt = 0.04
uinp = uinput.to_numpy()
y_rk = np.zeros(shape=(len(uinp),3))
y_init = [0.0157, 0.0296, 0.227]
y_rk[0,:] = y_init
for i in range(len(uinp)):
if i>0:
yprev = y_rk[i-1][:,np.newaxis]
y_rk[i,:] = runge_kutta(state_model,yprev,dt,uinp[i-1],uinp[i]).T
Plot hasil simulasi numerik untuk propagasi sikap dari wahana yang dikaji pada selang waktu
25 detik
label = [r'$\phi$',r'$\theta$',r'$\psi$']
fig,ax = plt.subplots(1,3,figsize=(15,4))
for i, axes in enumerate(ax):
axes.grid(ls="--",lw=0.5,color="black")
axes.plot(time_rk,np.degrees(y_rk[:,i]),lw=2.5,color='b')
axes.set_ylabel(label[i]+' (deg)')
axes.set_xlim(0,time_rk[-1])
axes.set_xlabel('time (s)')
No. 3
Data penerbangan yang diberikan berupa flight_03.csv dan akan dilakukan “Trajectory
Reconstruction”.
a. Lakukan rekonstruksi lintas terbang dari data yang diberikan. Plot hasilnya baik dalam
Tata Acuan Koordinat (TAK) NED maupun ECEF WGS-84
b. Plot hasil lintas terbang pada Google Earth
c. Tentukan lokasi (bandara) tempat pendaratan berdasarkan data dan hasil rekonstruksi
Solusi No.3
Impor beberapa modul yang akan digunakan pada program ini
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# from matplotlib import style
Baca data yang diberikan untuk mengecek bentuk data, dimana data navigasi pesawat telah
tersimpan dalam file .csv yang diberikan
df = pd.read_csv("flight_03.csv")
df
Apabila data diatas diplot terhadap waktu, maka akan didapatkan visualisasi seperti pada
dibawah.
time_s = np.linspace(0, df.shape[0] * 0.1, df.shape[0])
label = ["Ground Speed (m/s)", "Track angle (deg)", "Vertical Speed (m/s)"]
fig, ax = plt.subplots(2,2, figsize=(12, 8))
for i, axes in enumerate(ax.flatten()):
if i < 3:
if i == 1:
chi_deg = df.iloc[:, i+1].values * np.rad2deg(i) % 360
axes.plot(time_s, chi_deg, "--")
else:
axes.plot(time_s, df.iloc[:, i+1], "--")
axes.set_xlabel("time (s)", fontsize=12)
axes.set_ylabel(label[i], fontsize=12)
axes.set_xlim(0)
else:
axes.remove()
Gambar 13. Plot Data Navigasi Pesawat
Propagasi posisi pesawat pada TAK Kinematiknya dapat diformulasikan pada persamaan
berikut ini
𝑉𝑠 = 𝑉𝑘 . 𝑐𝑜𝑠(𝜒) . 𝑐𝑜𝑠(𝛾)
𝑉𝐸 = 𝑉𝑘 . 𝑠𝑖𝑛(𝜒) . 𝑐𝑜𝑠(𝛾)
ℎ = −𝑉𝑘 . 𝑠𝑖𝑛(𝛾)
Dari data yang disediakan, tidak ada sudut gamma. Sehingga kita perlu menghitungnya melalui
hubungan antara h dan VK seperti berikut ini
ℎ = −𝑉𝑘 . 𝑠𝑖𝑛(𝛾)
𝑉𝑘
𝛾 = −sin−1
ℎ
Code program yang dibuat untuk menghitung sudut gamma disajikan seperti berikut
Hasil perhitungan gamma dapat dilihat pada kolom paling kanan di gambar berikut
Gambar 14. Data Hasil Perhitungan Gamma
Untuk melihat plot data gamma pada selang waktu tertentu, dibuat code program seperti berikut
Visualisasi dari hasil perhitungan gamma berdasarkan data yang lainnya dapat dilihat pada
kurva di sebelah kanan bawah
Gambar 15. Plot Data Beberapa Parameter dari Data yang diberikan dan dari Perhitungan Sudut Gamma
a. Setelah semua data yang diperlukan telah tersedia, maka Trajectory Reconstruction dari
pesawat ini dapat dilakukan. Setelah itu dilanjutkan dengan membuat program untuk model
matematika berdasarkan persamaan propagasi posisi pada bagian sebelumnya
from numpy import float64, cos, sin
Plot hasil Trajectory Reconstruction pada TAK NED dan ketinggian dari pesawat tersebut
dapat dilihat pada gambar berikut ini
Gambar 16. Plot Hasil Trajectory Reconstruction dan Ketinggian Terbang Pesawat
Selanjutnya dilakukan transformasi dari TAK NED ke ECEF-WGS84. Dengan beberapa
kondisi awal yang diketahui pada TAK WGS84
• Latitude = -0.106821841 rad
• Longitude = 1.861220837 rad
• h = 182.88 m
Code program untuk mentransformasikan TAK ini dibuat seperti berikut ini
Impor modul “navpy” ke dalam program. Modul ini diambil dari website :
https://github.com/NavPy/NavPy
Dalam mengimpor modul, lokasi folder modul ini harus berada dalam directory yang sama
dengan lokasi penyimpanan file program. Hal ini sangat penting karena ketika akan melakukan
running pada program, komputer hanya akan bekerja pada satu file directory yang sama.
Apabila file modul tidak berada dalam satu directory, maka program tidak akan dapat membaca
modul tersebut. Plot hasil trajectrory reconstruction pada TAK ECEF-WGS 84 yang telah
didapat
hgps_m = ystorage[:, 2]
axes[1].plot(hgps_m)
axes[1].set_xlabel("Time (s)", fontsize=14)
axes[1].set_ylabel("Altitude (m)", fontsize=14)
Dapat dilihat bahwa plot hasil rekonstruksi pada TAK NED dan TAK ECEF-WGS 84,
keduanya sudah sangat mirip. Namun perbedaannya hanya terdapat pada besaran pada sumbu
vertikal dan horizontal. Hal ini menunjukkan bahwa, code program yang telah dibuat sudah
benar dan tervalidasi. Selain itu, plot ketinggian terbang pesawat juga sudah menunjukkan hasil
yang masuk akal, dimana terlihat jelas ketinggian pesawat ketika take-off, cruise, hingga
landing dalam kurun waktu tertentu.
b. Agar hasil simulasi lebih menarik dan realistis, hasil rekonstruksi diatas juga diplot pada
Google Earth. Sebelum melakukan plot, modul kml yang yang telah disediakan perlu diimpor
ke dalam program.
Data program tersebut diambil dari data pada TAK ECEF-WGS 84. Dengan bantuan aplikasi
Google Earth, output dari simulasi diatas yang diberi nama “trajectory-sim” dimasukkan.
Sehingga didapatlah plot pada Google Earth seperti berikut
Code program untuk men-generate file .kml yang menjadi file input ke aplikasi Google
Earth dibuat oleh Pak Javen tahun 2019. Penjelasan lebih mendalam mengenai rekonstruksi
terbang pesawat akan dibahas lebih mendalam pada bagian berikutnya.
c. Untuk menentukan pesawat berangkat dan tiba di lokasi yang mana, selain dari Gambar
18 diperlukan untuk menganalisa pesawat dari kurva latitude vs longitude-nya. Dengan
mengetahui kondisi awalnya
• Latitude = -6.07 derajat
• Longitude = 106.6 derajat
Sehingga titik itu akan berada pada tanda silang pada kurva dibawah ini
Dan apabila dibandingkan dengan Gambar 18 pada plot Google Earth, lokasi tanda silang
tersebut berada di Bandara Soekarna-Hatta di Cengkareng. Lalu sesuai dengan kurvanya,
pesawat akan mendarat di kota Palembang, yaitu Bandara Internasional Sultan Mahmud
Badaruddin II. Namun apabila diteliti lebih dalam, posisi mendarat tidak persis tepat di
bandara, melainkan terdapat sedikit perbedaan yang ditandai dengan garis putih pada gambar
dibawah ini.
Jadi dapat disimpulkan bahwa pesawat tersebut terbang dari Bandara Soekarno-Hatta
di Cengkareng dan mendarat di Bandara Internasional Sultan Mahmud Badaruddin II
di Kota Palembang, sekalipun ada error yang terjadi.
References
No. 1
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import pandas as pd
df = pd.read_csv("doublet.csv")
df
uinput = pd.read_csv('doublet.csv')
plt.figure(figsize=(8,4))
plt.plot(uinput.time_s, uinput.doublet)
_ = plt.xlim(0, 20)
_ = plt.xlabel('time (s)', fontsize=12)
_ = plt.ylabel('input', fontsize=12)
## Iteration Number 1
def discretize_method(A, B, u, x_init, dt):
""" Discretization method for model integration-1 """
phi = compute_phi(A, dt)
psi = phi * dt
x = np.zeros((len(u), 2))
x[0, :] = x_init.T
for i in range(len(u)):
if i > 0:
xi = np.dot(phi, x[i-1][np.newaxis].T) + np.dot(psi, B) * u[i]
x[i, :] = xi.flatten()
return x
def compute_phi(A, dt):
""" To compute state transition matrix """
phi = np.zeros(A.shape, dtype=float)
for i in range(10):
phi += np.linalg.matrix_power(A, i) * dt**i / np.math.factorial(i)
return phi
## Iteration Number 2 ##
def discretize_method_i(A, B, u, x_init, dt):
""" Discretization method for model integration-2 """
phi_i = compute_phi(A, dt)
psi_i = phi_i * dt
x = np.zeros((len(u), 2))
x[0, :] = x_init.T
for i in range(len(u)):
if i > 0:
xi = np.dot(phi_i, x[i-1][np.newaxis].T) + np.dot(psi_i, B) * u[i]
x[i, :] = xi.flatten()
return x
uinput = pd.read_csv('pqr_input.csv')
uinput
plt.plot(uinput["p_radps"],lw=2,color='r')
plt.plot(uinput["q_radps"],lw=2,color='b')
plt.plot(uinput["r_radps"],lw=2,color='g')
plt.ylabel('radps')
plt.title("PQR Input Model")
plt.grid(ls="--",lw=0.5,color="black")
plt.legend(['p','q','r'])
plt.xlim(0,len(uinput))
plt.show()
def state_model(xstate,u):
p = u[0]
q = u[1]
r = u[2]
phi = xstate[0]
theta = xstate[1]
phi_dot = p + tan(theta)*(q*sin(phi)+r*phi)
theta_dot = q*cos(phi) - r*phi
psi_dot = (q*sin(phi)+r*cos(phi))/cos(theta)
xdot = [phi_dot,theta_dot,psi_dot]
return np.reshape(np.array(xdot),(-1,1))
def runge_kutta(statemodel,xstate,dt,u1,u2):
k1 = dt*statemodel(xstate,u1)
k2 = dt*statemodel(xstate+k1*dt/2,(u1+u2)/2)
k3 = dt*statemodel(xstate+k2*dt/2,(u1+u2)/2)
k4 = dt*statemodel(xstate+k3*dt,(u1+u2)/2)
k = (k1+2*k2+2*k3+k4)/6
return xstate + k
dt = 0.04
uinp = uinput.to_numpy()
y_rk = np.zeros(shape=(len(uinp),3))
y_init = [0.0157, 0.0296, 0.227]
y_rk[0,:] = y_init
for i in range(len(uinp)):
if i>0:
yprev = y_rk[i-1][:,np.newaxis]
y_rk[i,:] = runge_kutta(state_model,yprev,dt,uinp[i-1],uinp[i]).T
time_rk = np.linspace(0,(len(uinput)-1)*dt,len(uinput))
label = [r'$\phi$',r'$\theta$',r'$\psi$']
fig,ax = plt.subplots(1,3,figsize=(15,4))
for i, axes in enumerate(ax):
axes.grid(ls="--",lw=0.5,color="black")
axes.plot(time_rk,np.degrees(y_rk[:,i]),lw=2.5,color='b')
axes.set_ylabel(label[i]+' (deg)')
axes.set_xlim(0,time_rk[-1])
axes.set_xlabel('time (s)')
No. 3
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# from matplotlib import style
df = pd.read_csv("flight_03.csv")
df
time_s = np.linspace(0, df.shape[0] * 0.1, df.shape[0])
label = ["Ground Speed (m/s)", "Track angle (deg)", "Vertical Speed (m/s)"]
fig, ax = plt.subplots(2,2, figsize=(12, 8))
for i, axes in enumerate(ax.flatten()):
if i < 3:
if i == 1:
chi_deg = df.iloc[:, i+1].values * np.rad2deg(i) % 360
axes.plot(time_s, chi_deg, "--")
else:
axes.plot(time_s, df.iloc[:, i+1], "--")
axes.set_xlabel("time (s)", fontsize=12)
axes.set_ylabel(label[i], fontsize=12)
axes.set_xlim(0)
else:
axes.remove()
axes[1].plot(ystorage[:, 2])
axes[1].set_xlabel("Time (s)", fontsize=14)
axes[1].set_ylabel("Altitude (m)", fontsize=14)
axes[1].legend(["Simulation"], fontsize=14)
hgps_m = ystorage[:, 2]
axes[1].plot(hgps_m)
axes[1].set_xlabel("Time (s)", fontsize=14)
axes[1].set_ylabel("Altitude (m)", fontsize=14)