Skip to content

Commit baed07e

Browse files
MRAC controller rearrangement
1 parent 9052bc1 commit baed07e

File tree

5 files changed

+76
-76
lines changed

5 files changed

+76
-76
lines changed

acsl_pychrono/config/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class MissionConfig:
88
# Run the simulator in Wrapper mode (more simulations automatically run sequentially)
99
wrapper_flag: bool = False
1010
# If True, perform real-time rendering of the simulation with Irrlicht
11-
visualization_flag: bool = True
11+
visualization_flag: bool = False
1212
# Dynamic camera options:
1313
# "fixed"
1414
# "default",

acsl_pychrono/control/MRAC/m_mrac.py

Lines changed: 23 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,53 +8,30 @@ def computeAdaptiveLaw(Gamma_gain, pi_vector, eTranspose_P_B):
88

99
return K_hat_state_dot
1010

11-
def reshapeAdaptiveGainsToMatrices(self):
12-
"""
13-
Reshapes all gain parameters to their correct (row, col) shape and converts them to np.matrix.
14-
This is intended to be called once after loading or updating gains stored as flat arrays.
15-
"""
16-
self.K_hat_x_tran = np.matrix(self.K_hat_x_tran.reshape(6,3))
17-
self.K_hat_r_tran = np.matrix(self.K_hat_r_tran.reshape(3,3))
18-
self.Theta_hat_tran = np.matrix(self.Theta_hat_tran.reshape(6,3))
19-
self.K_hat_x_rot = np.matrix(self.K_hat_x_rot.reshape(3,3))
20-
self.K_hat_r_rot = np.matrix(self.K_hat_r_rot.reshape(3,3))
21-
self.Theta_hat_rot = np.matrix(self.Theta_hat_rot.reshape(6,3))
11+
@ staticmethod
12+
def compute_eTransposePB(e, P, B):
13+
eTranspose_P_B = e.T * P * B
14+
return eTranspose_P_B
2215

23-
def compute_eTransposePB_OuterLoop(self):
24-
eTranspose_P_B_tran = self.e_tran.T * self.gains.P_tran * self.gains.B_tran
16+
@staticmethod
17+
def computeAllAdaptiveLaws(
18+
Gamma_x,
19+
x,
20+
Gamma_r,
21+
r,
22+
Gamma_Theta,
23+
Phi_regressor_vector,
24+
eTranspose_P_B
25+
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
26+
"""
27+
Compute all the classical MRAC adaptive laws
2528
26-
return eTranspose_P_B_tran
29+
Returns:
30+
- (K_hat_x_dot, K_hat_r_dot, Theta_hat_dot)
31+
"""
2732

28-
def computeAllAdaptiveLawsOuterLoop(self, eTranspose_P_B_tran):
29-
self.K_hat_x_tran_dot = self.computeAdaptiveLaw(
30-
-self.gains.Gamma_x_tran,
31-
self.x_tran,
32-
eTranspose_P_B_tran
33-
)
34-
self.K_hat_r_tran_dot = self.computeAdaptiveLaw(
35-
-self.gains.Gamma_r_tran,
36-
self.r_tran,
37-
eTranspose_P_B_tran
38-
)
39-
self.Theta_hat_tran_dot = self.computeAdaptiveLaw(
40-
self.gains.Gamma_Theta_tran,
41-
self.Phi_adaptive_tran_augmented,
42-
eTranspose_P_B_tran
43-
)
33+
K_hat_x_dot = M_MRAC.computeAdaptiveLaw(-Gamma_x, x, eTranspose_P_B)
34+
K_hat_r_dot = M_MRAC.computeAdaptiveLaw(-Gamma_r, r, eTranspose_P_B)
35+
Theta_hat_dot = M_MRAC.computeAdaptiveLaw(Gamma_Theta, Phi_regressor_vector, eTranspose_P_B)
4436

45-
def computeAllAdaptiveLawsInnerLoop(self, eTranspose_P_B_rot):
46-
self.K_hat_x_rot_dot = self.computeAdaptiveLaw(
47-
-self.gains.Gamma_x_rot,
48-
self.odein.angular_velocity,
49-
eTranspose_P_B_rot
50-
)
51-
self.K_hat_r_rot_dot = self.computeAdaptiveLaw(
52-
-self.gains.Gamma_r_rot,
53-
self.r_rot,
54-
eTranspose_P_B_rot
55-
)
56-
self.Theta_hat_rot_dot = self.computeAdaptiveLaw(
57-
self.gains.Gamma_Theta_rot,
58-
self.Phi_adaptive_rot_augmented,
59-
eTranspose_P_B_rot
60-
)
37+
return (K_hat_x_dot, K_hat_r_dot, Theta_hat_dot)

acsl_pychrono/control/MRAC/mrac.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from acsl_pychrono.control.base_mrac import BaseMRAC
99
from acsl_pychrono.control.MRAC.m_mrac import M_MRAC
1010

11-
class MRAC(M_MRAC, BaseMRAC, Control):
11+
class MRAC(BaseMRAC, Control):
1212
def __init__(self, gains: MRACGains, ode_input: OdeInput, flight_params: FlightParams, timestep: float):
1313
super().__init__(odein=ode_input)
1414
self.gains = gains
@@ -65,10 +65,18 @@ def computeControlAlgorithm(self, ode_input: OdeInput):
6565
self.mu_tran_raw = self.computeMuRawOuterLoop()
6666

6767
# Precompute e^T*P*B for outer loop
68-
eTranspose_P_B_tran = self.compute_eTransposePB_OuterLoop()
68+
eTranspose_P_B_tran = M_MRAC.compute_eTransposePB(self.e_tran, self.gains.P_tran, self.gains.B_tran)
6969

7070
# Outer Loop Adaptive Laws
71-
self.computeAllAdaptiveLawsOuterLoop(eTranspose_P_B_tran)
71+
(self.K_hat_x_tran_dot,
72+
self.K_hat_r_tran_dot,
73+
self.Theta_hat_tran_dot
74+
) = M_MRAC.computeAllAdaptiveLaws(
75+
self.gains.Gamma_x_tran, self.x_tran,
76+
self.gains.Gamma_r_tran, self.r_tran,
77+
self.gains.Gamma_Theta_tran, self.Phi_adaptive_tran_augmented,
78+
eTranspose_P_B_tran
79+
)
7280

7381
# Outer Loop Safety Mechanism
7482
self.mu_x, self.mu_y, self.mu_z = self.safety_mechanism.apply(self.mu_tran_raw)
@@ -129,10 +137,18 @@ def computeControlAlgorithm(self, ode_input: OdeInput):
129137
) = self.computeRegressorVectorInnerLoop()
130138

131139
# Precompute e^T*P*B for inner loop
132-
eTranspose_P_B_rot = self.compute_eTransposePB_InnerLoop()
140+
eTranspose_P_B_rot = M_MRAC.compute_eTransposePB(self.e_rot, self.gains.P_rot, self.gains.B_rot)
133141

134142
# Inner Loop Adaptive Laws
135-
self.computeAllAdaptiveLawsInnerLoop(eTranspose_P_B_rot)
143+
(self.K_hat_x_rot_dot,
144+
self.K_hat_r_rot_dot,
145+
self.Theta_hat_rot_dot
146+
) = M_MRAC.computeAllAdaptiveLaws(
147+
self.gains.Gamma_x_rot, self.odein.angular_velocity,
148+
self.gains.Gamma_r_rot, self.r_rot,
149+
self.gains.Gamma_Theta_rot, self.Phi_adaptive_rot_augmented,
150+
eTranspose_P_B_rot
151+
)
136152

137153
self.Moment_baseline = self.computeMomentBaselineInnerLoop()
138154

acsl_pychrono/control/MRAC/mrac_gains.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,23 @@ def __init__(self, flight_params: FlightParams):
3232
self.KD_tran_PD_baseline = np.matrix(1 * np.diag([8,8,3]))
3333

3434
# **Rotational** baseline parameters
35-
# self.KP_rot = np.matrix(1e2 * np.diag([1,1,0.5]))
36-
# self.KP_rot = np.matrix(5e1 * np.diag([0.1,0.1,0.5]))
37-
self.KP_rot = np.matrix(5e1 * np.diag([0.05,0.05,0.5]))
35+
# self.KP_rot = np.matrix(5e1 * np.diag([0.05,0.05,0.5]))
3836
# self.KI_rot = np.matrix(1e2 * np.diag([1,1,1]))
39-
self.KI_rot = np.matrix(1e2 * np.diag([1,1,1]))
37+
self.KP_rot = np.matrix(1 * np.diag([100,100,50]))
38+
self.KI_rot = np.matrix(0 * np.diag([0,0,0]))
4039

4140
# **Rotational** parameters for the PI baseline controller (Moment_baseline_PI)
42-
# self.KP_rot_PI_baseline = np.matrix(40 * np.diag([1,1,1]))
41+
# self.KP_rot_PI_baseline = np.matrix(200 * np.diag([1,1,0.3]))
4342
# self.KD_rot_PI_baseline = np.matrix(0 * np.diag([1,1,0.5]))
44-
# self.KI_rot_PI_baseline = np.matrix(1e-1 * np.diag([1,1,0.5]))
45-
self.KP_rot_PI_baseline = np.matrix(200 * np.diag([1,1,0.3]))
43+
# self.KI_rot_PI_baseline = np.matrix(1e2 * np.diag([10,10,0.5]))
44+
self.KP_rot_PI_baseline = np.matrix(40 * np.diag([1,1,0.5]))
4645
self.KD_rot_PI_baseline = np.matrix(0 * np.diag([1,1,0.5]))
47-
self.KI_rot_PI_baseline = np.matrix(1e2 * np.diag([10,10,0.5]))
46+
self.KI_rot_PI_baseline = np.matrix(0.1 * np.diag([1,1,0.5]))
4847

49-
# self.K_P_omega_ref = np.matrix(1.5e-1 * np.diag([5,5,10]))
50-
self.K_P_omega_ref = np.matrix(1.5e0 * np.diag([50,50,10]))
51-
self.K_I_omega_ref = np.matrix(1e2 * np.diag([1,1,1]))
48+
# self.K_P_omega_ref = np.matrix(1.5e0 * np.diag([50,50,10]))
49+
# self.K_I_omega_ref = np.matrix(1e2 * np.diag([1,1,1]))
50+
self.K_P_omega_ref = np.matrix(1.5e-1 * np.diag([5,5,10]))
51+
self.K_I_omega_ref = np.matrix(0 * np.diag([0,0,0]))
5252

5353
# ----------------------------------------------------------------
5454
# Translational Parameters MRAC
@@ -99,17 +99,17 @@ def __init__(self, flight_params: FlightParams):
9999
self.B_ref_rot = np.matrix(np.eye(3))
100100

101101
# **Rotational** parameters Lyapunov equation
102-
# self.Q_rot = np.matrix(7e-3 * np.diag([1,1,2]))
103-
self.Q_rot = np.matrix(7e-3 * np.diag([2,2,2]))
102+
# self.Q_rot = np.matrix(7e-3 * np.diag([2,2,2]))
103+
self.Q_rot = np.matrix(7e-3 * np.diag([1,1,1]))
104104
self.P_rot = np.matrix(linalg.solve_continuous_lyapunov(self.A_ref_rot.T, -self.Q_rot))
105105

106106
# **Rotational** adaptive parameters
107-
# self.Gamma_x_rot = np.matrix(1e1 * np.diag([1,1,10])) # Adaptive rates
108-
# self.Gamma_r_rot = np.matrix(1e-4 * np.diag([1,1,1])) # Adaptive rates
109-
# self.Gamma_Theta_rot = np.matrix(1e0 * np.diag([1,1,1,1,1,1])) # Adaptive rates
110-
self.Gamma_x_rot = np.matrix(1e4 * np.diag([1,1,1])) # Adaptive rates
111-
self.Gamma_r_rot = np.matrix(1e1 * np.diag([1,1,1])) # Adaptive rates
112-
self.Gamma_Theta_rot = np.matrix(1e2 * np.diag([1,1,1,1,1,1])) # Adaptive rates
107+
# self.Gamma_x_rot = np.matrix(1e4 * np.diag([1,1,1])) # Adaptive rates
108+
# self.Gamma_r_rot = np.matrix(1e1 * np.diag([1,1,1])) # Adaptive rates
109+
# self.Gamma_Theta_rot = np.matrix(1e2 * np.diag([1,1,1,1,1,1])) # Adaptive rates
110+
self.Gamma_x_rot = np.matrix(1e1 * np.diag([1,1,1])) # Adaptive rates
111+
self.Gamma_r_rot = np.matrix(1e-4 * np.diag([1,1,1])) # Adaptive rates
112+
self.Gamma_Theta_rot = np.matrix(1e0 * np.diag([1,1,1,1,1,1])) # Adaptive rates
113113

114114
# ----------------------------------------------------------------
115115
# Safety Mechanism Parameters

acsl_pychrono/control/base_mrac.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@
77
from acsl_pychrono.control.control import Control
88

99
class BaseMRAC():
10+
def reshapeAdaptiveGainsToMatrices(self):
11+
"""
12+
Reshapes all gain parameters to their correct (row, col) shape and converts them to np.matrix.
13+
This is intended to be called once after loading or updating gains stored as flat arrays.
14+
"""
15+
self.K_hat_x_tran = np.matrix(self.K_hat_x_tran.reshape(6,3))
16+
self.K_hat_r_tran = np.matrix(self.K_hat_r_tran.reshape(3,3))
17+
self.Theta_hat_tran = np.matrix(self.Theta_hat_tran.reshape(6,3))
18+
self.K_hat_x_rot = np.matrix(self.K_hat_x_rot.reshape(3,3))
19+
self.K_hat_r_rot = np.matrix(self.K_hat_r_rot.reshape(3,3))
20+
self.Theta_hat_rot = np.matrix(self.Theta_hat_rot.reshape(6,3))
21+
1022
def computeTrajectoryTrackingErrors(self, odein: OdeInput):
1123
"""
1224
Computes translational and rotational tracking errors and extracts the reference position.
@@ -160,11 +172,6 @@ def computeRegressorVectorInnerLoop(self):
160172

161173
return Phi_adaptive_rot, Phi_adaptive_rot_augmented
162174

163-
def compute_eTransposePB_InnerLoop(self):
164-
eTranspose_P_B_rot = self.e_rot.T * self.gains.P_rot * self.gains.B_rot
165-
166-
return eTranspose_P_B_rot
167-
168175
def computeMomentBaselineInnerLoop(self):
169176
Moment_baseline = np.cross(
170177
self.odein.angular_velocity.ravel(),

0 commit comments

Comments
 (0)