# Objective function weights Qx = sparse.diags([1.0, 0, 1.0, 0]) # Quadratic cost for states x0, x1, ..., x_N-1 QxN = sparse.diags([1.0, 0, 1.0, 0]) # Quadratic cost for xN Qu = 0.0 * sparse.eye(1) # Quadratic cost for u0, u1, ...., u_N-1 QDu = 0.1 * sparse.eye(1) # Quadratic cost for Du0, Du1, ...., Du_N-1 # Initial state phi0 = 15*2*np.pi/360 x0 = np.array([0, 0, phi0, 0]) # initial state # Prediction horizon Np = 40 K = MPCController(Ad,Bd,Np=Np, x0=x0,xref=xref,uminus1=uminus1, Qx=Qx, QxN=QxN, Qu=Qu,QDu=QDu, xmin=xmin,xmax=xmax,umin=umin,umax=umax,Dumin=Dumin,Dumax=Dumax) K.setup() # Kalman filter setup Cd = Cc Dd = Dc [nx, nu] = Bd.shape # number of states and number or inputs ny = np.shape(Cc)[0] # Kalman filter extended matrices Bd_kal = np.hstack([Bd, np.eye(nx)]) Dd_kal = np.hstack([Dd, np.zeros((ny, nx))]) Q_kal = np.diag([10,10,10,10])#np.eye(nx) * 100 R_kal = np.eye(ny) * 1
system_dyn = ode(f_ODE).set_integrator('vode', method='bdf') system_dyn.set_initial_value(x0, t0) system_dyn.set_f_params(0.0) # Prediction horizon Np = 30 K = MPCController(Ad, Bd, Np=Np, x0=x0, xref=xref, uminus1=uminus1, Qx=Qx, QxN=QxN, Qu=Qu, QDu=QDu, xmin=xmin, xmax=xmax, umin=umin, umax=umax, Dumin=Dumin, Dumax=Dumax, eps_feas=1e3) K.setup() # Simulate in closed loop [nx, nu] = Bd.shape # number of states and number or inputs len_sim = 40 # simulation length (s) nsim = int(len_sim / Ts) # simulation length(timesteps) xsim = np.zeros((nsim, nx))
QxN = sparse.diags([1, 1]) Qu = 0.01 * sparse.eye(1) QDu = 0.0 * sparse.eye(1) x0 = np.array([1, 0]) uminus1 = np.array([0.0]) Np = 1000 K = MPCController(Ad, Bd, Np=Np, x0=x0, xref=xref, uminus1=uminus1, Qx=Qx, QxN=QxN, Qu=Qu, QDu=QDu, xmin=xmin, xmax=xmax, umin=umin, umax=umax, Dumin=Dumin, Dumax=Dumax) K.setup() uMPC = K.output() # uMPC = K.output(return_u_seq=True) print(uMPC)
def simulate_pendulum_MPC(sim_options): use_NN_model = get_parameter(sim_options, 'use_NN_model') if use_NN_model: Ts_fit = 10e-3 # model was fitted with this sampling time ss_model = CartPoleStateSpaceModel(Ts=Ts_fit) nn_solution = NeuralStateSpaceSimulator(ss_model, Ts=Ts_fit) model_name = "model_SS_1step_nonoise.pkl" nn_solution.ss_model.load_state_dict( torch.load(os.path.join("models", model_name))) f_ODE = nn_solution.f_ODE else: f_ODE = f_ODE_wrapped seed_val = get_parameter(sim_options, 'seed_val') if seed_val is not None: np.random.seed(seed_val) Ac = get_parameter(sim_options, 'Ac') Bc = get_parameter(sim_options, 'Bc') Cc = np.array([[1., 0., 0., 0.], [0., 0., 1., 0.]]) Dc = np.zeros((2, 1)) [nx, nu] = Bc.shape # number of states and number or inputs ny = np.shape(Cc)[0] Ts_MPC = get_parameter(sim_options, 'Ts_MPC') ratio_Ts = int(Ts_MPC // Ts_fast) Ts_MPC = ( (Ts_MPC // Ts_fast)) * Ts_fast # make Ts_MPC an integer multiple of Ts_fast # Brutal forward euler discretization Ad = np.eye(nx) + Ac * Ts_MPC Bd = Bc * Ts_MPC Cd = Cc Dd = Dc # Standard deviation of the measurement noise on position and angle std_npos = get_parameter(sim_options, 'std_npos') std_nphi = get_parameter(sim_options, 'std_nphi') # Force disturbance std_dF = get_parameter(sim_options, 'std_dF') # disturbance power spectrum w_F = get_parameter(sim_options, 'w_F') # bandwidth of the force disturbance tau_F = 1 / w_F Hu = control.TransferFunction([1], [1 / w_F, 1]) Hu = Hu * Hu Hud = control.matlab.c2d(Hu, Ts_MPC) N_sim_imp = tau_F / Ts_MPC * 20 t_imp = np.arange(N_sim_imp) * Ts_MPC t, y = control.impulse_response(Hud, t_imp) y = y[0] std_tmp = np.sqrt(np.sum(y**2)) # np.sqrt(trapz(y**2,t)) Hu = Hu / (std_tmp) * std_dF N_skip = 1 #int(20 * tau_F // Ts_MPC) # skip initial samples to get a regime sample of d t_sim_d = get_parameter(sim_options, 'len_sim') # simulation length (s) N_sim_d = int(t_sim_d // Ts_MPC) N_sim_d = N_sim_d + N_skip + 1 e = np.random.randn(N_sim_d) te = np.arange(N_sim_d) * Ts_MPC _, d, _ = control.forced_response(Hu, te, e) d = d.ravel() p_ref = d[N_skip:] #td = np.arange(len(d)) * Ts_fast Np = get_parameter(sim_options, 'Np') Nc = get_parameter(sim_options, 'Nc') Qx = get_parameter(sim_options, 'Qx') QxN = get_parameter(sim_options, 'QxN') Qu = get_parameter(sim_options, 'Qu') QDu = get_parameter(sim_options, 'QDu') # Reference input and states xref_fun = get_parameter(sim_options, 'xref_fun') # reference state xref_fun_v = np.vectorize(xref_fun, signature='()->(n)') t0 = 0 xref_MPC = xref_fun(t0) uref = get_parameter(sim_options, 'uref') uminus1 = np.array( [0.0] ) # input at time step negative one - used to penalize the first delta u at time instant 0. Could be the same as uref. # Constraints xmin = np.array([-1000, -1000, -1000, -1000]) xmax = np.array([1000, 1000.0, 1000, 1000]) umin = np.array([-10]) umax = np.array([10]) Dumin = np.array([-100 * Ts_MPC]) Dumax = np.array([100 * Ts_MPC]) # Initialize simulation system phi0 = 0.0 #10*2*np.pi/360 x0 = np.array([0, 0, phi0, 0]) # initial state # system_dyn = ode(f_ODE_wrapped).set_integrator('vode', method='bdf') # dopri5 system_dyn = ode(f_ODE).set_integrator('dopri5') system_dyn.set_initial_value(x0, t0) system_dyn.set_f_params(0.0) QP_eps_rel = get_parameter(sim_options, 'QP_eps_rel') QP_eps_abs = get_parameter(sim_options, 'QP_eps_abs') # Emergency exit conditions EMERGENCY_STOP = False EMERGENCY_POS = 30.0 EMERGENCY_ANGLE = 90 * DEG_TO_RAD K = MPCController(Ad, Bd, Np=Np, Nc=Nc, x0=x0, xref=xref_MPC, uminus1=uminus1, Qx=Qx, QxN=QxN, Qu=Qu, QDu=QDu, xmin=xmin, xmax=xmax, umin=umin, umax=umax, Dumin=Dumin, Dumax=Dumax, eps_feas=1e3, eps_rel=QP_eps_rel, eps_abs=QP_eps_abs) try: K.setup(solve=True) # setup initial problem and also solve it except: EMERGENCY_STOP = True if not EMERGENCY_STOP: if K.res.info.status != 'solved': EMERGENCY_STOP = True # Basic Kalman filter design Q_kal = get_parameter(sim_options, 'Q_kal') R_kal = get_parameter(sim_options, 'R_kal') L, P, W = kalman_design_simple(Ad, Bd, Cd, Dd, Q_kal, R_kal, type='predictor') x0_est = x0 KF = LinearStateEstimator(x0_est, Ad, Bd, Cd, Dd, L) # Simulate in closed loop len_sim = get_parameter(sim_options, 'len_sim') # simulation length (s) nsim = int( np.ceil(len_sim / Ts_MPC) ) # simulation length(timesteps) # watch out! +1 added, is it correct? t_vec = np.zeros((nsim, 1)) t_calc_vec = np.zeros( (nsim, 1)) # computational time to get MPC solution (+ estimator) status_vec = np.zeros((nsim, 1)) x_vec = np.zeros((nsim, nx)) x_ref_vec = np.zeros((nsim, nx)) y_vec = np.zeros((nsim, ny)) y_meas_vec = np.zeros((nsim, ny)) y_est_vec = np.zeros((nsim, ny)) x_est_vec = np.zeros((nsim, nx)) u_vec = np.zeros((nsim, nu)) x_MPC_pred = np.zeros( (nsim, Np + 1, nx)) # on-line predictions from the Kalman Filter nsim_fast = int(len_sim // Ts_fast) t_vec_fast = np.zeros((nsim_fast, 1)) x_vec_fast = np.zeros( (nsim_fast, nx)) # finer integration grid for performance evaluation x_ref_vec_fast = np.zeros( (nsim_fast, nx)) # finer integration grid for performance evaluatio u_vec_fast = np.zeros( (nsim_fast, nu)) # finer integration grid for performance evaluatio Fd_vec_fast = np.zeros((nsim_fast, nu)) # t_int_vec_fast = np.zeros((nsim_fast, 1)) emergency_vec_fast = np.zeros((nsim_fast, 1)) # t_pred_all = t0 + np.arange(nsim + Np + 1) * Ts_MPC Xref_MPC_all = xref_fun_v(t_pred_all) t_step = t0 x_step = x0 u_MPC = None for idx_fast in range(nsim_fast): ## Determine step type: fast simulation only or MPC step idx_MPC = idx_fast // ratio_Ts run_MPC = (idx_fast % ratio_Ts) == 0 # Output for step i # Ts_MPC outputs if run_MPC: # it is also a step of the simulation at rate Ts_MPC t_vec[idx_MPC, :] = t_step x_vec[idx_MPC, :] = x_step #system_dyn.y xref_MPC = np.array([p_ref[idx_MPC], 0.0, 0.0, 0.0]) #xref_MPC = xref_fun(t_step) # reference state t_pred = t_step + np.arange(Np + 1) * Ts_MPC x_ref_vec[idx_MPC, :] = xref_MPC if not EMERGENCY_STOP: # u_MPC, info_MPC = K.output(return_x_seq=True, return_status=True) # u[i] = k(\hat x[i]) possibly computed at time instant -1 u_MPC, info_MPC = K.output( return_status=True, return_x_seq=True ) # u[i] = k(\hat x[i]) possibly computed at time instant -1 else: u_MPC = np.zeros(nu) if not EMERGENCY_STOP: if info_MPC['status'] != 'solved': EMERGENCY_STOP = True if not EMERGENCY_STOP: #pass x_MPC_pred[idx_MPC, :, :] = info_MPC[ 'x_seq'] # x_MPC_pred[i,i+1,...| possibly computed at time instant -1] u_vec[idx_MPC, :] = u_MPC y_step = Cd.dot(x_step) # y[i] from the system ymeas_step = np.copy(y_step) ymeas_step[0] += std_npos * np.random.randn() ymeas_step[1] += std_nphi * np.random.randn() y_vec[idx_MPC, :] = y_step y_meas_vec[idx_MPC, :] = ymeas_step if not EMERGENCY_STOP: status_vec[idx_MPC, :] = (info_MPC['status'] != 'solved') if np.abs(ymeas_step[0]) > EMERGENCY_POS or np.abs( ymeas_step[1]) > EMERGENCY_ANGLE: EMERGENCY_STOP = True # Ts_fast outputs t_vec_fast[idx_fast, :] = t_step x_vec_fast[idx_fast, :] = x_step #system_dyn.y x_ref_vec_fast[idx_fast, :] = xref_MPC u_fast = u_MPC u_vec_fast[idx_fast, :] = u_fast Fd_vec_fast[idx_fast, :] = 0.0 emergency_vec_fast[idx_fast, :] = EMERGENCY_STOP ## Update to step i+1 # Controller simulation step at rate Ts_MPC if run_MPC: time_calc_start = time.perf_counter() # Kalman filter: update and predict #KF.update(ymeas_step) # \hat x[i|i] #KF.predict(u_MPC) # \hat x[i+1|i] KF.predict_update(u_MPC, ymeas_step) # MPC update if not EMERGENCY_STOP: #Xref_MPC = Xref_MPC_all[idx_MPC:idx_MPC + Np + 1] K.update( KF.x, u_MPC, xref=xref_MPC) # update with measurement and reference #K.update(KF.x, u_MPC, xref=xref_MPC) # update with measurement and reference t_calc_vec[idx_MPC, :] = time.perf_counter() - time_calc_start if t_calc_vec[idx_MPC, :] > 2 * Ts_MPC: EMERGENCY_STOP = True # System simulation step at rate Ts_fast time_integrate_start = time.perf_counter() system_dyn.set_f_params(u_fast) system_dyn.integrate(t_step + Ts_fast) x_step = system_dyn.y #x_step = x_step + f_ODE(t_step, x_step, u_fast)*Ts_fast t_int_vec_fast[ idx_fast, :] = time.perf_counter() - time_integrate_start # Time update t_step += Ts_fast simout = { 't': t_vec, 'x': x_vec, 'u': u_vec, 'y': y_vec, 'y_meas': y_meas_vec, 'x_ref': x_ref_vec, 'x_MPC_pred': x_MPC_pred, 'status': status_vec, 'Fd_fast': Fd_vec_fast, 't_fast': t_vec_fast, 'x_fast': x_vec_fast, 'x_ref_fast': x_ref_vec_fast, 'u_fast': u_vec_fast, 'emergency_fast': emergency_vec_fast, 'KF': KF, 'K': K, 'nsim': nsim, 'Ts_MPC': Ts_MPC, 't_calc': t_calc_vec, 't_int_fast': t_int_vec_fast, 'use_NN_model': use_NN_model } return simout
x0_est = x0 KF = LinearStateEstimator(x0_est, Ad, Bd, Cd, Dd, L) # Prediction horizon Np = 200 # Initialize controller K = MPCController(Ad, Bd, Np=Np, x0=x0, xref=xref, uminus1=uminus1, Qx=Qx, QxN=QxN, Qu=Qu, QDu=QDu, xmin=xmin, xmax=xmax, umin=umin, umax=umax, Dumin=Dumin, Dumax=Dumax, eps_feas=1e3) K.setup() # Simulate in closed loop [nx, nu] = Bd.shape # number of states and number or inputs len_sim = 10 # simulation length (s) nsim = int(len_sim / Ts) # simulation length(timesteps) x_vec = np.zeros((nsim, nx))
# Initial state x0 = np.array([0.1, 0.2]) # initial state # Prediction horizon Np = 25 Nc = 25 K = MPCController(Ad, Bd, Np=Np, Nc=Nc, x0=x0, xref=xref, uref=uref, uminus1=uminus1, Qx=Qx, QxN=QxN, Qu=Qu, QDu=QDu, xmin=xmin, xmax=xmax, umin=umin, umax=umax, Dumin=Dumin, Dumax=Dumax) K.setup() # Simulate in closed loop [nx, nu] = Bd.shape # number of states and number or inputs len_sim = 30 # simulation length (s) nsim = int(len_sim / Ts) # simulation length(timesteps) xsim = np.zeros((nsim, nx))
def simulate_pendulum_MPC(sim_options): seed_val = get_parameter(sim_options,'seed_val') if seed_val is not None: np.random.seed(seed_val) # In[Sample times] Ts_MPC = get_parameter(sim_options, 'Ts_MPC') ratio_Ts = int(Ts_MPC // Ts_PID) # In[Real System] Cc = np.array([[1., 0., 0., 0.], [0., 0., 1., 0.]]) Cd = np.copy(Cc) nx, nu = 4,1 ny = 2 # In[initialize simulation system] t0 = 0 phi0 = -0.0 * 2 * np.pi / 360 # initial angle x0 = np.array([0, 0, phi0, 0]) # initial state #system_dyn = ode(f_ODE_wrapped).set_integrator('vode', method='bdf') # dopri5 system_dyn = ode(f_ODE_wrapped).set_integrator('dopri5') # dopri5 # system_dyn = ode(f_ODE_wrapped).set_integrator('dopri5') system_dyn.set_initial_value(x0, t0) system_dyn.set_f_params(0.0) #In[MPC params --model] Acl_c = get_parameter(sim_options, 'Acl_c') Bcl_c = get_parameter(sim_options, 'Bcl_c') Ccl_c = np.array([[1., 0., 0], [0., 0., 1]]) Dcl_c = np.zeros((2, 1)) ncl_x, ncl_u = Bcl_c.shape # number of states and number or inputs #ncl_y = np.shape(Ccl_c)[0] #In[MPC matrices discretization] Acl_d = np.eye(ncl_x) + Acl_c*Ts_MPC Bcl_d = Bcl_c*Ts_MPC Ccl_d = Ccl_c Dcl_d = Dcl_c x0_cl = np.array([0,0,phi0]) M_cl = LinearStateSpaceSystem(A=Acl_d, B=Bcl_d, C=Ccl_d, D=Dcl_d, x0=x0_cl) # MPC parameters Np = get_parameter(sim_options, 'Np') Nc = get_parameter(sim_options, 'Nc') Qx = get_parameter(sim_options, 'Qx') QxN = get_parameter(sim_options, 'QxN') Qr = get_parameter(sim_options, 'Qr') QDr = get_parameter(sim_options, 'QDr') # Constraints #xmin = np.array([-1.5, -100, -100]) #xmax = np.array([1.5, 100.0, 100]) #umin = np.array([-10]) #umax = np.array([10]) #Dumin = np.array([-100 * Ts_MPC_def]) #Dumax = np.array([100 * Ts_MPC_def]) QP_eps_rel = get_parameter(sim_options, 'QP_eps_rel') QP_eps_abs = get_parameter(sim_options, 'QP_eps_abs') # Emergency exit conditions EMERGENCY_STOP = False EMERGENCY_POS = 2.0 EMERGENCY_ANGLE = 30 * DEG_TO_RAD # Reference input and states xref_cl_fun = get_parameter(sim_options, 'xref_cl_fun') # reference state xref_cl_fun_v = np.vectorize(xref_cl_fun, signature='()->(n)') t0 = 0 xref_MPC = xref_cl_fun(t0) uref = get_parameter(sim_options, 'uref') uminus1 = np.array([0.0]) # input at time step negative one - used to penalize the first delta u at time instant 0. Could be the same as uref. kMPC = MPCController(Acl_d, Bcl_d, Np=Np, Nc=Nc, x0=x0_cl, xref=xref_MPC, uminus1=uminus1, Qx=Qx, QxN=QxN, Qu=Qr, QDu=QDr, eps_feas=1e3, eps_rel=QP_eps_rel, eps_abs=QP_eps_abs) try: kMPC.setup(solve=True) # setup initial problem and also solve it except: EMERGENCY_STOP = True if not EMERGENCY_STOP: if kMPC.res.info.status != 'solved': EMERGENCY_STOP = True # In[initialize PID] # Default controller parameters - P = -100.0 I = -1 D = -20 N = 100.0 kP = control.tf(P,1, Ts_PID) kI = I*Ts_PID*control.tf([0, 1], [1,-1], Ts_PID) kD = D*control.tf([N, -N], [1.0, Ts_PID*N - 1], Ts_PID) PID_tf = kP + kD + kI PID_ss = control.ss(PID_tf) k_PID = LinearStateSpaceSystem(A=PID_ss.A, B=PID_ss.B, C=PID_ss.C, D=PID_ss.D) # In[initialize noise] # Standard deviation of the measurement noise on position and angle std_npos = get_parameter(sim_options, 'std_npos') std_nphi = get_parameter(sim_options, 'std_nphi') # Force disturbance std_dF = get_parameter(sim_options, 'std_dF') # Disturbance power spectrum w_F = get_parameter(sim_options, 'w_F') # bandwidth of the force disturbance tau_F = 1 / w_F Hu = control.TransferFunction([1], [1 / w_F, 1]) Hu = Hu * Hu Hud = control.matlab.c2d(Hu, Ts_PID) N_sim_imp = tau_F / Ts_PID * 20 t_imp = np.arange(N_sim_imp) * Ts_PID t, y = control.impulse_response(Hud, t_imp) y = y[0] std_tmp = np.sqrt(np.sum(y ** 2)) # np.sqrt(trapz(y**2,t)) Hu = Hu / (std_tmp) * std_dF N_skip = int(20 * tau_F // Ts_PID) # skip initial samples to get a regime sample of d t_sim_d = get_parameter(sim_options, 'len_sim') # simulation length (s) N_sim_d = int(t_sim_d // Ts_PID) N_sim_d = N_sim_d + N_skip + 1 e = np.random.randn(N_sim_d) te = np.arange(N_sim_d) * Ts_PID _, d, _ = control.forced_response(Hu, te, e) d = d.ravel() # Simulate in closed loop len_sim = get_parameter(sim_options, 'len_sim') # simulation length (s) nsim = int(len_sim // Ts_MPC) #int(np.ceil(len_sim / Ts_MPC)) # simulation length(timesteps) # watch out! +1 added, is it correct? t_vec = np.zeros((nsim, 1)) status_vec = np.zeros((nsim,1)) x_vec = np.zeros((nsim, nx)) x_ref_vec = np.zeros((nsim, ncl_x)) y_vec = np.zeros((nsim, ny)) y_meas_vec = np.zeros((nsim, ny)) u_vec = np.zeros((nsim, nu)) x_model_vec = np.zeros((nsim,3)) nsim_fast = int(len_sim // Ts_PID) t_vec_fast = np.zeros((nsim_fast, 1)) x_vec_fast = np.zeros((nsim_fast, nx)) # finer integration grid for performance evaluation ref_phi_vec_fast = np.zeros((nsim_fast, 1)) y_meas_vec_fast = np.zeros((nsim_fast, ny)) x_ref_vec_fast = np.zeros((nsim_fast, nx)) # finer integration grid for performance evaluatio u_vec_fast = np.zeros((nsim_fast, nu)) # finer integration grid for performance evaluatio Fd_vec_fast = np.zeros((nsim_fast, nu)) # t_int_vec_fast = np.zeros((nsim_fast, 1)) emergency_vec_fast = np.zeros((nsim_fast, 1)) # t_step = t0 x_step = x0 u_PID = None t_pred_all = t0 + np.arange(nsim + Np + 1) * Ts_MPC Xref_MPC_all = xref_cl_fun_v(t_pred_all) for idx_fast in range(nsim_fast): ## Determine step type: fast simulation only or MPC step idx_MPC = idx_fast // ratio_Ts run_MPC_controller = (idx_fast % ratio_Ts) == 0 y_step = Cd.dot(x_step) # y[i] from the system ymeas_step = np.copy(y_step) ymeas_step[0] += std_npos * np.random.randn() ymeas_step[1] += std_nphi * np.random.randn() y_meas_vec_fast[idx_fast,:] = ymeas_step # Output for step i # Ts_MPC outputs if run_MPC_controller: # it is also a step of the simulation at rate Ts_MPC if idx_MPC < nsim: t_vec[idx_MPC, :] = t_step y_vec[idx_MPC,:] = y_step y_meas_vec[idx_MPC,:] = ymeas_step u_vec[idx_MPC, :] = u_PID x_model_vec[idx_MPC, :] = M_cl.x.ravel() xref_MPC = xref_cl_fun(t_step) x_ref_vec[idx_MPC,:] = xref_MPC.ravel() if not EMERGENCY_STOP: phi_ref_MPC, info_MPC = kMPC.output(return_status=True) # u[i] = k(\hat x[i]) possibly computed at time instant -1 else: phi_ref_MPC = np.zeros(nu) # PID angle CONTROLLER ref_phi = phi_ref_MPC.ravel() error_phi = ref_phi - ymeas_step[1] u_PID = k_PID.output(error_phi) u_PID[u_PID > 10.0] = 10.0 u_PID[u_PID < -10.0] = -10.0 u_TOT = u_PID # Ts_fast outputs t_vec_fast[idx_fast,:] = t_step x_vec_fast[idx_fast, :] = x_step #system_dyn.y u_vec_fast[idx_fast,:] = u_TOT Fd_vec_fast[idx_fast,:] = 0.0 ref_phi_vec_fast[idx_fast,:] = ref_phi ## Update to step i+1 k_PID.update(error_phi) # Controller simulation step at rate Ts_MPC if run_MPC_controller: M_cl.update(ref_phi) if not EMERGENCY_STOP: x_cl = np.array([x_step[0], x_step[1], x_step[2]]) Xref_MPC = Xref_MPC_all[idx_MPC:idx_MPC + Np + 1] xref_MPC = Xref_MPC_all[idx_MPC] kMPC.update(x_cl, phi_ref_MPC, xref=xref_MPC) # update with measurement and reference # System simulation step at rate Ts_fast time_integrate_start = time.perf_counter() system_dyn.set_f_params(u_TOT) system_dyn.integrate(t_step + Ts_PID) x_step = system_dyn.y t_int_vec_fast[idx_fast,:] = time.perf_counter() - time_integrate_start # Time update t_step += Ts_PID simout = {'t': t_vec, 'x': x_vec, 'u': u_vec, 'y': y_vec, 'y_meas': y_meas_vec, 'x_ref': x_ref_vec, 'status': status_vec, 'Fd_fast': Fd_vec_fast, 't_fast': t_vec_fast, 'x_fast': x_vec_fast, 'x_ref_fast': x_ref_vec_fast, 'u_fast': u_vec_fast, 'y_meas_fast': y_meas_vec_fast, 'emergency_fast': emergency_vec_fast, 'PID_tf': PID_tf, 'Ts_MPC': Ts_MPC, 'ref_phi_fast': ref_phi_vec_fast, 'x_model': x_model_vec, 't_int_fast': t_int_vec_fast } return simout