@@ -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
0 commit comments