66from acsl_pychrono .flight_params import FlightParams
77from acsl_pychrono .control .control import Control
88from acsl_pychrono .control .base_mrac import BaseMRAC
9+ from acsl_pychrono .control .MRAC .m_mrac import M_MRAC
910
10- class MRAC (BaseMRAC , Control ):
11- def __init__ (self , gains : MRACGains , ode_input : OdeInput , flight_params : FlightParams ):
11+ class MRAC (M_MRAC , BaseMRAC , Control ):
12+ def __init__ (self , gains : MRACGains , ode_input : OdeInput , flight_params : FlightParams , timestep : float ):
13+ super ().__init__ (odein = ode_input )
1214 self .gains = gains
13- self .odein = ode_input
1415 self .fp = flight_params
16+ self .timestep = timestep
1517 self .safety_mechanism = OuterLoopSafetyMechanism (gains , self .fp .G_acc )
1618 self .dy = np .zeros ((self .gains .number_of_states , 1 ))
19+ # Initial conditions
20+ self .y = np .zeros ((self .gains .number_of_states , 1 ))
1721
18- def computeControlAlgorithm (self , y , ode_input : OdeInput ):
22+ def computeControlAlgorithm (self , ode_input : OdeInput ):
1923 """
2024 Compute all intermediate variables and control inputs once per RK4 step to compute the dy for RK4.
2125 """
2226 # Update the vehicle state and user-defined trajectory
2327 self .odein = ode_input
2428
2529 # ODE state
26- self .state_phi_ref_diff = y [0 :2 ] # State of the differentiator for phi_ref (roll_ref)
27- self .state_theta_ref_diff = y [2 :4 ] # State of the differentiator for theta_ref (pitch_ref)
28- self .x_ref_tran = y [4 :10 ] # Reference model state
29- self .integral_position_tracking_ref = y [10 :13 ] # Integral of ('translational_position_in_I_ref' - 'translational_position_in_I_user')
30- self .K_hat_x_tran = y [13 :31 ] # \hat{K}_x (translational)
31- self .K_hat_r_tran = y [31 :40 ] # \hat{K}_r (translational)
32- self .Theta_hat_tran = y [40 :58 ] # \hat{\Theta} (translational)
33- self .omega_ref = y [58 :61 ] # Reference model rotational dynamics
34- self .K_hat_x_rot = y [61 :70 ] # \hat{K}_x (rotational)
35- self .K_hat_r_rot = y [70 :79 ] # \hat{K}_r (rotational)
36- self .Theta_hat_rot = y [79 :97 ] # \hat{\Theta} (rotational)
37- self .integral_e_rot = y [97 :100 ] # Integral of 'e_rot' = (angular_velocity - omega_ref)
38- self .integral_angular_error = y [100 :103 ] # Integral of angular_error = attitude - attitude_ref
39- self .integral_e_omega_ref_cmd = y [103 :106 ] #Integral of (omega_ref - omega_cmd)
30+ self .state_phi_ref_diff = self . y [0 :2 ] # State of the differentiator for phi_ref (roll_ref)
31+ self .state_theta_ref_diff = self . y [2 :4 ] # State of the differentiator for theta_ref (pitch_ref)
32+ self .x_ref_tran = self . y [4 :10 ] # Reference model state
33+ self .integral_position_tracking_ref = self . y [10 :13 ] # Integral of ('translational_position_in_I_ref' - 'translational_position_in_I_user')
34+ self .K_hat_x_tran = self . y [13 :31 ] # \hat{K}_x (translational)
35+ self .K_hat_r_tran = self . y [31 :40 ] # \hat{K}_r (translational)
36+ self .Theta_hat_tran = self . y [40 :58 ] # \hat{\Theta} (translational)
37+ self .omega_ref = self . y [58 :61 ] # Reference model rotational dynamics
38+ self .K_hat_x_rot = self . y [61 :70 ] # \hat{K}_x (rotational)
39+ self .K_hat_r_rot = self . y [70 :79 ] # \hat{K}_r (rotational)
40+ self .Theta_hat_rot = self . y [79 :97 ] # \hat{\Theta} (rotational)
41+ self .integral_e_rot = self . y [97 :100 ] # Integral of 'e_rot' = (angular_velocity - omega_ref)
42+ self .integral_angular_error = self . y [100 :103 ] # Integral of angular_error = attitude - attitude_ref
43+ self .integral_e_omega_ref_cmd = self . y [103 :106 ] #Integral of (omega_ref - omega_cmd)
4044
4145 # Reshapes all adaptive gains to their correct (row, col) shape as matrices
4246 self .reshapeAdaptiveGainsToMatrices ()
@@ -136,13 +140,14 @@ def computeControlAlgorithm(self, y, ode_input: OdeInput):
136140
137141 (self .u2 ,
138142 self .u3 ,
139- self .u4
143+ self .u4 ,
144+ _
140145 ) = self .computeU2_U3_U4 ()
141146
142147 # Compute individual motor thrusts
143148 self .motor_thrusts = Control .computeMotorThrusts (self .fp , self .u1 , self .u2 , self .u3 , self .u4 )
144149
145- def ode (self , t , y , ode_input : OdeInput ):
150+ def ode (self , t , y ):
146151 """
147152 Function called by RK4. Assumes `computeControlAlgorithm` was called
148153 at the beginning of the integration step to update internal state.
@@ -162,50 +167,4 @@ def ode(self, t, y, ode_input: OdeInput):
162167 self .dy [100 :103 ] = self .angular_error
163168 self .dy [103 :106 ] = self .omega_ref - self .omega_cmd
164169
165- return np .array (self .dy )
166-
167- def reshapeAdaptiveGainsToMatrices (self ):
168- """
169- Reshapes all gain parameters to their correct (row, col) shape and converts them to np.matrix.
170- This is intended to be called once after loading or updating gains stored as flat arrays.
171- """
172- self .K_hat_x_tran = np .matrix (self .K_hat_x_tran .reshape (6 ,3 ))
173- self .K_hat_r_tran = np .matrix (self .K_hat_r_tran .reshape (3 ,3 ))
174- self .Theta_hat_tran = np .matrix (self .Theta_hat_tran .reshape (6 ,3 ))
175- self .K_hat_x_rot = np .matrix (self .K_hat_x_rot .reshape (3 ,3 ))
176- self .K_hat_r_rot = np .matrix (self .K_hat_r_rot .reshape (3 ,3 ))
177- self .Theta_hat_rot = np .matrix (self .Theta_hat_rot .reshape (6 ,3 ))
178-
179- def computeAllAdaptiveLawsOuterLoop (self , eTranspose_P_B_tran ):
180- self .K_hat_x_tran_dot = self .computeAdaptiveLawMRAC (
181- - self .gains .Gamma_x_tran ,
182- self .x_tran ,
183- eTranspose_P_B_tran
184- )
185- self .K_hat_r_tran_dot = self .computeAdaptiveLawMRAC (
186- - self .gains .Gamma_r_tran ,
187- self .r_tran ,
188- eTranspose_P_B_tran
189- )
190- self .Theta_hat_tran_dot = self .computeAdaptiveLawMRAC (
191- self .gains .Gamma_Theta_tran ,
192- self .Phi_adaptive_tran_augmented ,
193- eTranspose_P_B_tran
194- )
195-
196- def computeAllAdaptiveLawsInnerLoop (self , eTranspose_P_B_rot ):
197- self .K_hat_x_rot_dot = self .computeAdaptiveLawMRAC (
198- - self .gains .Gamma_x_rot ,
199- self .odein .angular_velocity ,
200- eTranspose_P_B_rot
201- )
202- self .K_hat_r_rot_dot = self .computeAdaptiveLawMRAC (
203- - self .gains .Gamma_r_rot ,
204- self .r_rot ,
205- eTranspose_P_B_rot
206- )
207- self .Theta_hat_rot_dot = self .computeAdaptiveLawMRAC (
208- self .gains .Gamma_Theta_rot ,
209- self .Phi_adaptive_rot_augmented ,
210- eTranspose_P_B_rot
211- )
170+ return np .array (self .dy )
0 commit comments