Buckets:
| import numpy as np | |
| from scipy.sparse.linalg import spsolve | |
| from beam import neb_beam_matrices, newmark1step_mrhs | |
| from noise import generate_noise_temporal | |
| def kalman_filter(z, x_est, P, A, B, H, Q, R, u=0): | |
| # Prediction | |
| x_pred = A @ x_est + B * u | |
| P_pred = A @ P @ A.T + Q | |
| # Update | |
| K = P_pred @ H.T @ np.linalg.inv(H @ P_pred @ H.T + R) | |
| x_est = x_pred + K @ (z - H @ x_pred) | |
| P = (np.eye(len(x_est)) - K @ H) @ P_pred | |
| return x_est, P | |
| def run_simulation(nstep=1000, delta=0.01, q=0.0001, r=0.0001, T=3, Kp=5e-1, Ki=1e-1, Kd=1e-2, mu=1e-1, beta=0.25, gamma=0.5, L=500, a=5, b=5, E=70000, rho=2700e-9, cy=1e-4, nx=10, nA=None, control_type='pid', meas_location='B'): | |
| if nA is None: | |
| nA = nx | |
| S = a * b | |
| Ix = a * b**3 / 12 | |
| dx = L / nx | |
| time = np.arange(delta, (nstep+1)*delta, delta) | |
| time0 = np.concatenate([[0], time]) | |
| ixe = np.arange(dx, L+dx, dx) | |
| is_matlab = True | |
| vseed1 = 0 | |
| vseed2 = 1 | |
| vseed3 = 2 | |
| npt = nx + 1 | |
| ndof = 2 * npt | |
| ndo1 = ndof - 2 | |
| induA = 2 * nA - 1 | |
| induB = 2 * nx - 1 | |
| fpert = generate_noise_temporal(time0, 1, q, vseed1, is_matlab) | |
| mpert = generate_noise_temporal(time0, 1, r, vseed2, is_matlab) | |
| fA = np.zeros_like(time0) | |
| fA[len(fA)//10:] = 1 | |
| ffull = np.zeros((ndof, nstep+1)) | |
| Kfull, Cfull, Mfull = neb_beam_matrices(nx, dx, E, Ix, rho, S, cy) | |
| K = Kfull[2:, 2:] | |
| C = Cfull[2:, 2:] | |
| M = Mfull[2:, 2:] | |
| f = ffull[2:, :] | |
| f[induA, :] = fA + fpert | |
| u0 = np.zeros(ndo1) | |
| v0 = np.zeros(ndo1) | |
| u = np.zeros((ndo1, nstep+1)) | |
| v = np.zeros((ndo1, nstep+1)) | |
| a = np.zeros((ndo1, nstep+1)) | |
| a0 = spsolve(M, f[:, 0] - C @ v0 - K @ u0) | |
| a[:, 0] = a0 | |
| u[:, 0] = u0 | |
| v[:, 0] = v0 | |
| integ_e = 0 | |
| prev_e = 0 | |
| t0 = 1.0 | |
| u_ref = (time0 >= t0).astype(float) | |
| e_set = [0] | |
| indu_meas = induA if meas_location == 'A' else induB | |
| # Initialize Kalman if needed | |
| if control_type in ['kalman', 'pid_kalman']: | |
| x_est = np.array([0.0, 0.0]) | |
| P = np.eye(2) * 0.1 | |
| A = np.array([[1, delta], [0, 1]]) | |
| H = np.array([1, 0]) | |
| Q = np.eye(2) * q | |
| R = r | |
| for step in range(1, nstep+1): | |
| if control_type == 'pid': | |
| u_meas = u[indu_meas, step-1] + mpert[step] | |
| e = u_ref[step] - u_meas | |
| integ_e += e * delta | |
| de = (e - prev_e) / delta | |
| Fpid = Kp * e + Ki * integ_e + Kd * de | |
| f_k = np.zeros(ndo1) | |
| f_k[induA] = Fpid + fpert[step] | |
| prev_e = e | |
| e_set.append(e) | |
| elif control_type == 'kalman': | |
| f_k = np.zeros(ndo1) | |
| f_k[induA] = fpert[step] # open loop | |
| e_set.append(0) # no error for kalman | |
| elif control_type == 'pid_kalman': | |
| z = u[indu_meas, step-1] + mpert[step] | |
| x_est, P = kalman_filter(z, x_est, P, A, np.zeros(2), H, Q, R) | |
| u_est = x_est[0] | |
| e = u_ref[step] - u_est | |
| integ_e += e * delta | |
| de = (e - prev_e) / delta | |
| Fpid = Kp * e + Ki * integ_e + Kd * de | |
| f_k = np.zeros(ndo1) | |
| f_k[induA] = Fpid + fpert[step] | |
| prev_e = e | |
| e_set.append(e) | |
| u[:, step], v[:, step], a[:, step] = newmark1step_mrhs(M, C, K, f_k, u[:, step-1], v[:, step-1], a[:, step-1], delta, beta, gamma) | |
| return time0, ixe, u, v, a, e_set, fA |
Xet Storage Details
- Size:
- 3.46 kB
- Xet hash:
- f31866b534726ac51b82cb08c92e4a70a302e37fb8eaaa7308d6c71ce4493bda
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.