Skip to content

Commit fdee0f7

Browse files
Funnel MRAC to outer loop
Added Funnel MRAC to the outer loop
1 parent fbf869a commit fdee0f7

File tree

2 files changed

+209
-2
lines changed

2 files changed

+209
-2
lines changed

drone_bb_test_COMPLETE_with_wrapper.py

Lines changed: 206 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,8 @@ def WrapperMain_function(target_folder, controller_type, wrapper_control_paramet
987987

988988
# controller_type = 'HybridRobustTwoLayerMRACwithBASELINE'
989989

990+
# controller_type = 'FunnelMRACwithBASELINE'
991+
990992
# ----------------------------------------------------------------
991993
# %%%%%%%%%%%%%%%%%%%%%%
992994
# ----------------------------------------------------------------
@@ -1072,7 +1074,16 @@ def WrapperMain_function(target_folder, controller_type, wrapper_control_paramet
10721074
summation_hybrid_P_tran,summation_hybrid_P_rot,s_hybrid_tran,s_hybrid_rot,tollerance_time_reset_series,e_transient_tran,
10731075
e_transient_rot,summation_hybrid_transient_P_tran,summation_hybrid_transient_P_rot,s_hybrid_transient_tran,
10741076
s_hybrid_transient_rot] = Gains.HybridRobustTwoLayerMRACwithBASELINE(mass_total_estimated, air_density_estimated, surface_area_estimated, drag_coefficient_matrix_estimated)
1075-
1077+
1078+
elif controller_type == 'FunnelMRACwithBASELINE':
1079+
# Gains Funnel MRAC with Baseline
1080+
[number_of_states,size_DATA,KP_tran,KD_tran,KI_tran,KP_tran_PD_baseline,KD_tran_PD_baseline,KP_rot,KP_rot_PI_baseline,
1081+
KD_rot_PI_baseline,KI_rot_PI_baseline,K_P_omega_ref,A_tran,B_tran,A_tran_bar,Lambda_bar,Theta_tran_adaptive_bar,
1082+
A_ref_tran,B_ref_tran,Gamma_x_tran,Gamma_r_tran,Gamma_Theta_tran,Gamma_Theta_tran,Q_tran,P_tran,K_x_tran_bar,K_r_tran_bar,A_rot,
1083+
B_rot,A_ref_rot,B_ref_rot,Q_rot,P_rot,Gamma_x_rot,Gamma_r_rot,Gamma_Theta_rot,eta_bar_funnel,M_funnel,u_max,u_min,
1084+
Delta_u_min,nu_funnel] = Gains.FunnelMRACwithBASELINE(mass_total_estimated, air_density_estimated, surface_area_estimated, drag_coefficient_matrix_estimated)
1085+
1086+
10761087
#%% Control Algorithms ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
10771088

10781089
# Initial conditions
@@ -2613,6 +2624,178 @@ def HybridRobustTwoLayerMRACwithBASELINE(t, y):
26132624

26142625
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
26152626

2627+
def FunnelMRACwithBASELINE(t, y):
2628+
"""
2629+
This function defines the system of equations of the Funnel MRAC with Baseline CONTROLLER that need to be integrated
2630+
2631+
"""
2632+
global mu_x, mu_y, mu_z, u1, roll_ref, pitch_ref, roll_ref_dot, pitch_ref_dot, roll_ref_ddot, pitch_ref_ddot
2633+
global angular_position_ref_dot, angular_position_ref_ddot, Jacobian_matrix_inverse, angular_position_dot
2634+
global angular_error_dot, u2, u3, u4, mu_baseline_tran, mu_adaptive_tran, Moment_baseline, Moment_adaptive
2635+
global mu_PD_baseline_tran, Moment_baseline_PI
2636+
2637+
2638+
state_phi_ref_diff = y[0:2] # State of the differentiator for phi_ref (roll_ref)
2639+
state_theta_ref_diff = y[2:4] # State of the differentiator for theta_ref (pitch_ref)
2640+
x_ref_tran = y[4:10] # Reference model state
2641+
integral_position_tracking_ref = y[10:13] # Integral of ('translational_position_in_I_ref' - 'translational_position_in_I_user')
2642+
K_hat_x_tran = y[13:31] # \hat{K}_x (translational)
2643+
K_hat_r_tran = y[31:40] # \hat{K}_r (translational)
2644+
Theta_hat_tran = y[40:58] # \hat{\Theta} (translational)
2645+
omega_ref = y[58:61] # Reference model rotational dynamics
2646+
K_hat_x_rot = y[61:70] # \hat{K}_x (rotational)
2647+
K_hat_r_rot = y[70:79] # \hat{K}_r (rotational)
2648+
Theta_hat_rot = y[79:97] # \hat{\Theta} (rotational)
2649+
integral_e_rot = y[97:100] # Integral of 'e_rot' = (angular_velocity - omega_ref)
2650+
eta_funnel = y[100] # eta used to compute the funnel diameter
2651+
2652+
K_hat_x_tran = np.matrix(K_hat_x_tran.reshape(6,3))
2653+
K_hat_r_tran = np.matrix(K_hat_r_tran.reshape(3,3))
2654+
Theta_hat_tran = np.matrix(Theta_hat_tran.reshape(6,3))
2655+
K_hat_x_rot = np.matrix(K_hat_x_rot.reshape(3,3))
2656+
K_hat_r_rot = np.matrix(K_hat_r_rot.reshape(3,3))
2657+
Theta_hat_rot = np.matrix(Theta_hat_rot.reshape(6,3))
2658+
2659+
e_tran = x_tran - x_ref_tran
2660+
e_rot = angular_velocity - omega_ref
2661+
translational_position_in_I_ref = x_ref_tran[0:3]
2662+
2663+
R3 = np.matrix([[math.cos(yaw), -math.sin(yaw), 0],
2664+
[math.sin(yaw), math.cos(yaw), 0],
2665+
[ 0, 0, 1]])
2666+
2667+
R2 = np.matrix([[ math.cos(pitch), 0, math.sin(pitch)],
2668+
[ 0, 1, 0],
2669+
[-math.sin(pitch), 0, math.cos(pitch)]])
2670+
2671+
R1 = np.matrix([[1, 0, 0],
2672+
[0, math.cos(roll), -math.sin(roll)],
2673+
[0, math.sin(roll), math.cos(roll)]])
2674+
2675+
R_from_loc_to_glob = R3*R2*R1
2676+
R_from_glob_to_loc = R_from_loc_to_glob.transpose()
2677+
2678+
Phi_adaptive_tran = -0.5 * LA.norm(R_from_glob_to_loc * translational_velocity_in_I) * (R_from_glob_to_loc * translational_velocity_in_I)
2679+
2680+
Jacobian_matrix_inverse = np.matrix([[1, (math.sin(roll)*math.sin(pitch))/math.cos(pitch), (math.cos(roll)*math.sin(pitch))/math.cos(pitch)],
2681+
[0, math.cos(roll), -math.sin(roll)],
2682+
[0, math.sin(roll)/math.cos(pitch), math.cos(roll)/math.cos(pitch)]])
2683+
2684+
angular_position_dot = Jacobian_matrix_inverse * angular_velocity # Time derivative of the Euler angles
2685+
roll_dot = angular_position_dot[0] # phi_dot
2686+
pitch_dot = angular_position_dot[1] # theta_dot
2687+
# yaw_dot = angular_position_dot[2] # psi_dot
2688+
2689+
Jacobian_matrix_dot = np.matrix(np.zeros((3,3)))
2690+
Jacobian_matrix_dot[0,2] = -math.cos(pitch) * pitch_dot
2691+
Jacobian_matrix_dot[1,1] = -math.sin(roll) * roll_dot
2692+
Jacobian_matrix_dot[1,2] = math.cos(roll) * math.cos(pitch) * roll_dot - math.sin(roll) * math.sin(pitch) * pitch_dot
2693+
Jacobian_matrix_dot[2,1] = -math.cos(roll) * roll_dot
2694+
Jacobian_matrix_dot[2,2] = -math.cos(pitch) * math.sin(roll) * roll_dot - math.cos(roll) * math.sin(pitch) * pitch_dot
2695+
2696+
r_tran = mass_total_estimated * (-KI_tran*integral_position_tracking_ref + translational_acceleration_in_I_user + KP_tran*translational_position_in_I_user + KD_tran*translational_velocity_in_I_user)
2697+
2698+
x_ref_tran_dot = A_ref_tran*x_ref_tran + B_ref_tran*r_tran
2699+
2700+
mu_PD_baseline_tran = -mass_total_estimated * (KP_tran_PD_baseline * (translational_position_in_I - translational_position_in_I_ref) + KD_tran_PD_baseline * (translational_velocity_in_I - x_ref_tran[3:6]) - x_ref_tran_dot[3:6])
2701+
2702+
Phi_adaptive_tran_augmented = np.matrix(np.block([[mu_PD_baseline_tran],
2703+
[Phi_adaptive_tran]]))
2704+
Theta_tran_adaptive_bar_augmented = np.matrix(np.block([[np.identity(3)],
2705+
[Theta_tran_adaptive_bar]]))
2706+
2707+
mu_baseline_tran = K_x_tran_bar.T * x_tran + K_r_tran_bar.T * r_tran - Theta_tran_adaptive_bar_augmented.T * Phi_adaptive_tran_augmented
2708+
mu_adaptive_tran = K_hat_x_tran.T * x_tran + K_hat_r_tran.T * r_tran - Theta_hat_tran.T * Phi_adaptive_tran_augmented
2709+
mu_tran = mu_PD_baseline_tran + mu_baseline_tran + mu_adaptive_tran
2710+
2711+
H_function_funnel = eta_bar_funnel - eta_funnel**2 - e_tran.T * M_funnel * e_tran
2712+
Ve_funnel = (e_tran.T * P_tran * e_tran)/H_function_funnel
2713+
2714+
K_hat_x_tran_dot = -Gamma_x_tran * x_tran * e_tran.T * (P_tran + M_funnel * Ve_funnel.item()) * B_tran/H_function_funnel
2715+
K_hat_r_tran_dot = -Gamma_r_tran * r_tran * e_tran.T * (P_tran + M_funnel * Ve_funnel.item()) * B_tran/H_function_funnel
2716+
Theta_hat_tran_dot = Gamma_Theta_tran * Phi_adaptive_tran_augmented * e_tran.T * (P_tran + M_funnel * Ve_funnel.item()) * B_tran/H_function_funnel
2717+
2718+
mu_x = mu_tran[0].item()
2719+
mu_y = mu_tran[1].item()
2720+
mu_z = mu_tran[2].item()
2721+
2722+
u1 = math.sqrt(mu_x ** 2 + mu_y ** 2 + (mass_total_estimated * G_acc - mu_z) ** 2)
2723+
2724+
xi_funnel_temp = (u_max - u1)/max(u1 - u_min, Delta_u_min)
2725+
xi_funnel = (e_tran.T * Q_tran * e_tran >= 2 * Ve_funnel * eta_funnel**2 * xi_funnel_temp + nu_funnel) * (H_function_funnel > 0) * xi_funnel_temp
2726+
2727+
calculation_var_A = -(1/u1) * (mu_x * math.sin(yaw_ref) - mu_y * math.cos(yaw_ref))
2728+
roll_ref = math.atan2(calculation_var_A, math.sqrt(1 - calculation_var_A ** 2))
2729+
2730+
pitch_ref = math.atan2(-(mu_x * math.cos(yaw_ref) + mu_y * math.sin(yaw_ref)), (mass_total_estimated * G_acc - mu_z))
2731+
2732+
internal_state_differentiator_phi_ref_diff = A_phi_ref * state_phi_ref_diff + B_phi_ref*roll_ref
2733+
internal_state_differentiator_theta_ref_diff = A_theta_ref * state_theta_ref_diff + B_theta_ref*pitch_ref
2734+
2735+
roll_ref_dot = np.asarray(C_phi_ref*state_phi_ref_diff).item()
2736+
pitch_ref_dot = np.asarray(C_theta_ref*state_theta_ref_diff).item()
2737+
2738+
roll_ref_ddot = np.asarray(C_phi_ref*internal_state_differentiator_phi_ref_diff).item()
2739+
pitch_ref_ddot = np.asarray(C_theta_ref*internal_state_differentiator_theta_ref_diff).item()
2740+
2741+
angular_position_ref_dot = np.array([roll_ref_dot, pitch_ref_dot, yaw_ref_dot]).reshape(3,1)
2742+
angular_position_ref_ddot = np.array([roll_ref_ddot, pitch_ref_ddot, yaw_ref_ddot]).reshape(3,1)
2743+
2744+
angular_error_dot = angular_position_dot - angular_position_ref_dot
2745+
2746+
Jacobian_matrix = np.matrix([[1, 0, -math.sin(pitch)],
2747+
[0, math.cos(roll), math.sin(roll) * math.cos(pitch)],
2748+
[0, -math.sin(roll), math.cos(roll) * math.cos(pitch)]])
2749+
2750+
omega_cmd = Jacobian_matrix * (-KP_rot*angular_error + angular_position_ref_dot)
2751+
omega_cmd_dot = Jacobian_matrix_dot * (-KP_rot*angular_error + angular_position_ref_dot) + Jacobian_matrix * (-KP_rot*angular_error_dot + angular_position_ref_ddot)
2752+
2753+
omega_ref_dot = -K_P_omega_ref*(omega_ref - omega_cmd) + omega_cmd_dot
2754+
2755+
r_rot = K_P_omega_ref * omega_cmd + omega_cmd_dot
2756+
2757+
Phi_adaptive_rot = np.array([[angular_velocity[1].item() * angular_velocity[2].item()],
2758+
[angular_velocity[0].item() * angular_velocity[2].item()],
2759+
[angular_velocity[0].item() * angular_velocity[1].item()]])
2760+
2761+
Moment_baseline_PI = -I_matrix_estimated * (KP_rot_PI_baseline*e_rot + KD_rot_PI_baseline*(angular_acceleration - omega_ref_dot) + KI_rot_PI_baseline*integral_e_rot - omega_ref_dot)
2762+
2763+
Phi_adaptive_rot_augmented = np.matrix(np.block([[Moment_baseline_PI],
2764+
[Phi_adaptive_rot]]))
2765+
2766+
K_hat_x_rot_dot = -Gamma_x_rot * angular_velocity * e_rot.T * P_rot * B_rot
2767+
K_hat_r_rot_dot = -Gamma_r_rot * r_rot * e_rot.T * P_rot * B_rot
2768+
Theta_hat_rot_dot = Gamma_Theta_rot * Phi_adaptive_rot_augmented * e_rot.T * P_rot * B_rot
2769+
2770+
Moment_baseline = np.cross(angular_velocity.ravel(), (I_matrix_estimated * angular_velocity).ravel()).reshape(3,1)
2771+
Moment_adaptive = K_hat_x_rot.T * angular_velocity + K_hat_r_rot.T * r_rot - Theta_hat_rot.T * Phi_adaptive_rot_augmented
2772+
2773+
Moment = Moment_baseline_PI + Moment_baseline + Moment_adaptive
2774+
2775+
u2 = Moment[0].item()
2776+
u3 = Moment[1].item()
2777+
u4 = Moment[2].item()
2778+
2779+
2780+
dy[0:2] = internal_state_differentiator_phi_ref_diff
2781+
dy[2:4] = internal_state_differentiator_theta_ref_diff
2782+
dy[4:10] = x_ref_tran_dot
2783+
dy[10:13] = translational_position_in_I_ref - translational_position_in_I_user
2784+
dy[13:31] = K_hat_x_tran_dot.reshape(18,1)
2785+
dy[31:40] = K_hat_r_tran_dot.reshape(9,1)
2786+
dy[40:58] = Theta_hat_tran_dot.reshape(18,1)
2787+
dy[58:61] = omega_ref_dot
2788+
dy[61:70] = K_hat_x_rot_dot.reshape(9,1)
2789+
dy[70:79] = K_hat_r_rot_dot.reshape(9,1)
2790+
dy[79:97] = Theta_hat_rot_dot.reshape(18,1)
2791+
dy[97:100] = angular_velocity - omega_ref
2792+
dy[100] = eta_funnel * xi_funnel
2793+
2794+
return np.array(dy)
2795+
2796+
# ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2797+
2798+
26162799
my_frame_pos_GLOB = my_frame.GetPos()
26172800

26182801
#%% Irrlicht visualization
@@ -3624,6 +3807,28 @@ def HybridRobustTwoLayerMRACwithBASELINE(t, y):
36243807

36253808
flag_first_loop_controller = True
36263809
###################################################################
3810+
3811+
elif controller_type == 'FunnelMRACwithBASELINE':
3812+
# Integrating the ODEs through RK4 for Funnel MRAC with Baseline controller
3813+
yout = rk4singlestep(controller.FunnelMRACwithBASELINE, m_timestep, time_now, yin)
3814+
Y_list = np.append(Y_list,np.resize(yout,(number_of_states,1)), axis=1)
3815+
yin = yout
3816+
3817+
################### FUNNEL MRAC WITH BASELINE #####################
3818+
state_phi_ref_diff = yout[0:2] # State of the differentiator for phi_ref (roll_ref)
3819+
state_theta_ref_diff = yout[2:4] # State of the differentiator for theta_ref (pitch_ref)
3820+
x_ref_tran = yout[4:10] # Reference model state
3821+
integral_position_tracking_ref = yout[10:13] # Integral of ('translational_position_in_I_ref' - 'translational_position_in_I_user')
3822+
K_hat_x_tran = yout[13:31] # \hat{K}_x (translational)
3823+
K_hat_r_tran = yout[31:40] # \hat{K}_r (translational)
3824+
Theta_hat_tran = yout[40:58] # \hat{\Theta} (translational)
3825+
omega_ref = yout[58:61] # Reference model rotational dynamics
3826+
K_hat_x_rot = yout[61:70] # \hat{K}_x (rotational)
3827+
K_hat_r_rot = yout[70:79] # \hat{K}_r (rotational)
3828+
Theta_hat_rot = yout[79:97] # \hat{\Theta} (rotational)
3829+
integral_e_rot = yout[97:100] # Integral of 'e_rot' = (angular_velocity - omega_ref)
3830+
eta_funnel = yout[100] # eta used to compute the funnel diameter
3831+
###################################################################
36273832

36283833
# ----------------------------------------------------------------------------------------------------------------------------------------------------------------
36293834

loop.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
# controller_type = 'RobustMRACwithBASELINE'
4141

42-
controller_type = 'RobustTwoLayerMRACwithBASELINE'
42+
# controller_type = 'RobustTwoLayerMRACwithBASELINE'
4343

4444
# controller_type = 'HybridMRACwithBASELINE'
4545

@@ -49,6 +49,8 @@
4949

5050
# controller_type = 'HybridRobustTwoLayerMRACwithBASELINE'
5151

52+
controller_type = 'FunnelMRACwithBASELINE'
53+
5254
# ----------------------------------------------------------------
5355
# %%%%%%%%%%%%%%%%%%%%%%
5456
# ----------------------------------------------------------------

0 commit comments

Comments
 (0)