From 30a64631190c3b37891c58ed8e4bc103303c9eb4 Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Wed, 28 Aug 2024 16:23:12 -0300 Subject: [PATCH 01/14] Changes in integrate_system for pid controller --- ross/rotor_assembly.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/ross/rotor_assembly.py b/ross/rotor_assembly.py index cc1c849b5..526aa386b 100644 --- a/ross/rotor_assembly.py +++ b/ross/rotor_assembly.py @@ -2201,6 +2201,19 @@ def integrate_system(self, speed, F, t, **kwargs): K2 = get_array[0](kwargs.get("Ksdt", self.Ksdt())) F = get_array[1](F.T).T + # Check if there is any magnetic bearing + magnetic_bearings = [ + brg + for brg in self.bearing_elements + if isinstance(brg, MagneticBearingElement) + ] + if len(magnetic_bearings): + magnetic_force = lambda time_step, disp_resp: self.magnetic_bearing_controller( + magnetic_bearings, time_step, disp_resp + ) + else: + magnetic_force = lambda time_step, disp_resp: 0 + # Consider any additional RHS function (extra forces) add_to_RHS = kwargs.get("add_to_RHS") @@ -2214,6 +2227,9 @@ def integrate_system(self, speed, F, t, **kwargs): disp_resp=get_array[2](curr_state.get("y")), velc_resp=get_array[2](curr_state.get("ydot")), accl_resp=get_array[2](curr_state.get("y2dot")), + ) + magnetic_force( + time_step=curr_state.get("dt"), + disp_resp=get_array[2](curr_state.get("y")), ) ) @@ -2231,9 +2247,11 @@ def integrate_system(self, speed, F, t, **kwargs): raise Warning( "The bearing coefficients vary with speed. Therefore, C and K matrices are not being replaced by the matrices defined as input arguments." ) + + ignore_elements = [*magnetic_bearings, *brgs_with_var_coeffs] - C0 = self.C(speed_ref, ignore=brgs_with_var_coeffs) - K0 = self.K(speed_ref, ignore=brgs_with_var_coeffs) + C0 = self.C(speed_ref, ignore=ignore_elements) + K0 = self.K(speed_ref, ignore=ignore_elements) def rotor_system(step, **current_state): Cb, Kb = assemble_C_K_matrices( From 401b5fff9eb7108f86ada51fc700f792b794661c Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Wed, 28 Aug 2024 16:28:04 -0300 Subject: [PATCH 02/14] Add magnetic bearing controller --- ross/rotor_assembly.py | 84 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 73 insertions(+), 11 deletions(-) diff --git a/ross/rotor_assembly.py b/ross/rotor_assembly.py index 526aa386b..2abed66b5 100644 --- a/ross/rotor_assembly.py +++ b/ross/rotor_assembly.py @@ -2117,6 +2117,57 @@ def run_unbalance_response( return forced_response + def magnetic_bearing_controller(self, magnetic_bearings, time_step, disp_resp): + """ + This method allows the closed-loop control of the magnetic bearing. + The control technique used is PID and it controls axes x and y of each bearing. + + Parameters + ---------- + time_step : float + Time step in seconds. + disp_resp : array + Array of displacements along the rotor nodes. + + Returns + ------- + magnetic_force : array + Control force (external). + + Example + ------- + >>> response = rotor.run_time_response(speed, + ... F, + ... t, + ... method = "newmark") + + """ + + offset = 0 + setpoint = 1e-6 + dt = time_step + magnetic_force = np.zeros((self.ndof)) + + for elm in magnetic_bearings: + dofs = [self.number_dof * elm.n, self.number_dof * elm.n + 1] + for idx_dofs, value_dofs in enumerate(dofs): + err = setpoint - disp_resp[value_dofs] + + P = elm.kp_pid * err + elm.integral[idx_dofs] += elm.ki_pid * err * dt + D = elm.kd_pid * (err - elm.e0[idx_dofs]) / dt + + signal_pid = offset + P + elm.integral[idx_dofs] + D + magnetic_force[value_dofs] = ( + elm.ki * signal_pid + elm.ks * disp_resp[value_dofs] + ) + + elm.e0[idx_dofs] = err + elm.control_signal[idx_dofs].append(signal_pid) + elm.magnetic_force[idx_dofs].append(magnetic_force[value_dofs]) + + return magnetic_force + def integrate_system(self, speed, F, t, **kwargs): """Time integration for a rotor system. @@ -2208,12 +2259,14 @@ def integrate_system(self, speed, F, t, **kwargs): if isinstance(brg, MagneticBearingElement) ] if len(magnetic_bearings): - magnetic_force = lambda time_step, disp_resp: self.magnetic_bearing_controller( - magnetic_bearings, time_step, disp_resp + magnetic_force = ( + lambda time_step, disp_resp: self.magnetic_bearing_controller( + magnetic_bearings, time_step, disp_resp + ) ) else: magnetic_force = lambda time_step, disp_resp: 0 - + # Consider any additional RHS function (extra forces) add_to_RHS = kwargs.get("add_to_RHS") @@ -2227,9 +2280,10 @@ def integrate_system(self, speed, F, t, **kwargs): disp_resp=get_array[2](curr_state.get("y")), velc_resp=get_array[2](curr_state.get("ydot")), accl_resp=get_array[2](curr_state.get("y2dot")), - ) + magnetic_force( - time_step=curr_state.get("dt"), - disp_resp=get_array[2](curr_state.get("y")), + ) + + magnetic_force( + curr_state.get("dt"), + get_array[2](curr_state.get("y")), ) ) @@ -2247,7 +2301,7 @@ def integrate_system(self, speed, F, t, **kwargs): raise Warning( "The bearing coefficients vary with speed. Therefore, C and K matrices are not being replaced by the matrices defined as input arguments." ) - + ignore_elements = [*magnetic_bearings, *brgs_with_var_coeffs] C0 = self.C(speed_ref, ignore=ignore_elements) @@ -2269,8 +2323,12 @@ def rotor_system(step, **current_state): ) else: # Option 2 - C1 = get_array[0](kwargs.get("C", self.C(speed_ref))) - K1 = get_array[0](kwargs.get("K", self.K(speed_ref))) + C1 = get_array[0]( + kwargs.get("C", self.C(speed_ref, ignore=magnetic_bearings)) + ) + K1 = get_array[0]( + kwargs.get("K", self.K(speed_ref, ignore=magnetic_bearings)) + ) rotor_system = lambda step, **current_state: ( M, @@ -2280,8 +2338,12 @@ def rotor_system(step, **current_state): ) else: # Option 3 - C1 = get_array[0](kwargs.get("C", self.C(speed_ref))) - K1 = get_array[0](kwargs.get("K", self.K(speed_ref))) + C1 = get_array[0]( + kwargs.get("C", self.C(speed_ref, ignore=magnetic_bearings)) + ) + K1 = get_array[0]( + kwargs.get("K", self.K(speed_ref, ignore=magnetic_bearings)) + ) rotor_system = lambda step, **current_state: ( M, From f0a8fb9f3c408413abb41103ee50ed88b676ebe6 Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Thu, 5 Sep 2024 00:08:00 -0300 Subject: [PATCH 03/14] Add PID parameters --- ross/bearing_seal_element.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ross/bearing_seal_element.py b/ross/bearing_seal_element.py index 2cdb663dd..83755707c 100644 --- a/ross/bearing_seal_element.py +++ b/ross/bearing_seal_element.py @@ -1412,6 +1412,8 @@ class MagneticBearingElement(BearingElement): Pole angle in radians. kp_pid : float or int Proportional gain of the PID controller. + ki_pid : float or int + Integrative gain of the PID controller. kd_pid : float or int Derivative gain of the PID controller. k_amp : float or int @@ -1464,6 +1466,7 @@ def __init__( nw, alpha, kp_pid, + ki_pid, kd_pid, k_amp, k_sense, @@ -1478,6 +1481,7 @@ def __init__( self.nw = nw self.alpha = alpha self.kp_pid = kp_pid + self.ki_pid = ki_pid self.kd_pid = kd_pid self.k_amp = k_amp self.k_sense = k_sense @@ -1525,6 +1529,14 @@ def __init__( * pA[2] / (4.0 * pA[0] ** 2) ) + + self.ks = ks + self.ki = ki + self.integral = [0, 0] + self.e0 = [1e-6, 1e-6] + self.control_signal = [[], []] + self.magnetic_force = [[], []] + k = ki * pA[7] * pA[8] * (pA[5] + np.divide(ks, ki * pA[7] * pA[8])) c = ki * pA[7] * pA[6] * pA[8] # k = ki * k_amp*k_sense*(kp_pid+ np.divide(ks, ki*k_amp*k_sense)) From 0cbf2bfbe38993e9f784eee266d3eb08ce9104ac Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Thu, 5 Sep 2024 00:11:05 -0300 Subject: [PATCH 04/14] Changes in the external force system of the numerical integrator --- ross/rotor_assembly.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ross/rotor_assembly.py b/ross/rotor_assembly.py index 2abed66b5..66098a41d 100644 --- a/ross/rotor_assembly.py +++ b/ross/rotor_assembly.py @@ -2271,7 +2271,12 @@ def integrate_system(self, speed, F, t, **kwargs): add_to_RHS = kwargs.get("add_to_RHS") if add_to_RHS is None: - forces = lambda step, **curr_state: F[step, :] + forces = lambda step, **curr_state: F[step, :] + get_array[1]( + magnetic_force( + curr_state.get("dt"), + get_array[2](curr_state.get("y")), + ) + ) else: forces = lambda step, **curr_state: F[step, :] + get_array[1]( add_to_RHS( From d8035a0b46b1b0cc4b25e46f5dc607785d72a22b Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Sun, 22 Sep 2024 16:48:34 -0300 Subject: [PATCH 05/14] Changes in ki_pid configuration --- ross/bearing_seal_element.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/ross/bearing_seal_element.py b/ross/bearing_seal_element.py index 3188a5ca2..62acf57cc 100644 --- a/ross/bearing_seal_element.py +++ b/ross/bearing_seal_element.py @@ -1410,16 +1410,17 @@ class MagneticBearingElement(BearingElement): Number of windings alpha : float or int Pole angle in radians. - kp_pid : float or int - Proportional gain of the PID controller. - ki_pid : float or int - Integrative gain of the PID controller. - kd_pid : float or int - Derivative gain of the PID controller. k_amp : float or int Gain of the amplifier model. k_sense : float or int Gain of the sensor model. + kp_pid : float or int + Proportional gain of the PID controller. + kd_pid : float or int + Derivative gain of the PID controller. + ki_pid : float or int, optional + Integrative gain of the PID controller, must be provided + if using closed-loop response. tag : str, optional A tag to name the element Default is None. @@ -1468,11 +1469,11 @@ def __init__( ag, nw, alpha, - kp_pid, - ki_pid, - kd_pid, k_amp, k_sense, + kp_pid, + kd_pid, + ki_pid=None, tag=None, n_link=None, scale_factor=1, @@ -1484,11 +1485,11 @@ def __init__( self.ag = ag self.nw = nw self.alpha = alpha - self.kp_pid = kp_pid - self.ki_pid = ki_pid - self.kd_pid = kd_pid self.k_amp = k_amp self.k_sense = k_sense + self.kp_pid = kp_pid + self.kd_pid = kd_pid + self.ki_pid = ki_pid pL = [g0, i0, ag, nw, alpha, kp_pid, kd_pid, k_amp, k_sense] pA = [0, 0, 0, 0, 0, 0, 0, 0, 0] @@ -1540,7 +1541,7 @@ def __init__( self.e0 = [1e-6, 1e-6] self.control_signal = [[], []] self.magnetic_force = [[], []] - + k = ki * pA[7] * pA[8] * (pA[5] + np.divide(ks, ki * pA[7] * pA[8])) c = ki * pA[7] * pA[6] * pA[8] # k = ki * k_amp*k_sense*(kp_pid+ np.divide(ks, ki*k_amp*k_sense)) From 19bae5df0c863d2f4fc84fe29de4482dce687ae8 Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Sun, 22 Sep 2024 16:52:13 -0300 Subject: [PATCH 06/14] Add rotor_amb_example() --- ross/rotor_assembly.py | 162 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 152 insertions(+), 10 deletions(-) diff --git a/ross/rotor_assembly.py b/ross/rotor_assembly.py index 78ec61c34..99842c374 100644 --- a/ross/rotor_assembly.py +++ b/ross/rotor_assembly.py @@ -2118,9 +2118,9 @@ def run_unbalance_response( return forced_response def magnetic_bearing_controller(self, magnetic_bearings, time_step, disp_resp): - """ - This method allows the closed-loop control of the magnetic bearing. - The control technique used is PID and it controls axes x and y of each bearing. + r""" + This method allows the closed-loop control of the magnetic bearing using a PID design. + It controls axes x and y of each bearing. Parameters ---------- @@ -2134,13 +2134,9 @@ def magnetic_bearing_controller(self, magnetic_bearings, time_step, disp_resp): magnetic_force : array Control force (external). - Example - ------- - >>> response = rotor.run_time_response(speed, - ... F, - ... t, - ... method = "newmark") - + Examples + -------- + """ offset = 0 @@ -4568,3 +4564,149 @@ def rotor_example_6dof(): ) return Rotor(shaft_elem, [disk0, disk1], [bearing0, bearing1]) + + +def rotor_amb_example(): + r"""This function creates the model of a test rig rotor supported by magnetic bearings. + Details of the model can be found at doi.org/10.14393/ufu.di.2015.186. + + Returns + ------- + Rotor object. + + """ + + from ross.materials import Material + + steel_amb = Material(name="Steel", rho=7850, E=2e11, Poisson=0.3) + + # Shaft elements: + # fmt: off + Li = [ + 0.0, 0.012, 0.032, 0.052, 0.072, 0.092, 0.112, 0.1208, 0.12724, + 0.13475, 0.14049, 0.14689, 0.15299, 0.159170, 0.16535, 0.180350, + 0.1905, 0.2063, 0.2221, 0.2379, 0.2537, 0.2695, 0.2853, 0.3011, + 0.3169, 0.3327, 0.3363, 0.3485, 0.361, 0.3735, 0.3896, 0.4057, + 0.4218, 0.4379, 0.454, 0.4701, 0.4862, 0.5023, 0.5184, 0.5345, + 0.54465, 0.559650, 0.565830, 0.572010, 0.57811, 0.58451, 0.590250, + 0.59776, 0.6042, 0.613, 0.633, 0.645, + ] + Li = [round(i, 4) for i in Li] + L = [Li[i + 1] - Li[i] for i in range(len(Li) - 1)] + i_d = [0.0 for i in L] + o_d1 = [0.0 for i in L] + o_d1[0] = 6.35 + o_d1[1:5] = [32 for i in range(4)] + o_d1[5:14] = [34.8 for i in range(9)] + o_d1[14:16] = [1.2 * 49.9 for i in range(2)] + o_d1[16:27] = [19.05 for i in range(11)] + o_d1[27:29] = [0.8 * 49.9 for i in range(2)] + o_d1[29:39] = [19.05 for i in range(10)] + o_d1[39:41] = [1.2 * 49.9 for i in range(2)] + o_d1[41:49] = [34.8 for i in range(8)] + o_d1[49] = 34.8 + o_d1[50] = 6.35 + o_d = [i * 1e-3 for i in o_d1] + + shaft_elements = [ + ShaftElement( + L=l, + idl=idl, + odl=odl, + material=steel_amb, + shear_effects=True, + rotary_inertia=True, + gyroscopic=True, + ) + for l, idl, odl in zip(L, i_d, o_d) + ] + + # Disk elements: + n_list = [6, 7, 8, 9, 10, 11, 12, 13, 27, 29, 41, 42, 43, 44, 45, 46, 47, 48] + width = [ + 0.0088, 0.0064, 0.0075, 0.0057, + 0.0064, 0.0061, 0.0062, 0.0062, + 0.0124, 0.0124, 0.0062, 0.0062, + 0.0061, 0.0064, 0.0057, 0.0075, + 0.0064, 0.0088, + ] + o_disc = [ + 0.0249, 0.0249, 0.0249, 0.0249, + 0.0249, 0.0249, 0.0249, 0.0249, + 0.0600, 0.0600, 0.0249, 0.0249, + 0.0249, 0.0249, 0.0249, 0.0249, + 0.0249, 0.0249, + ] + i_disc = [ + 0.0139, 0.0139, 0.0139, 0.0139, + 0.0139, 0.0139, 0.0139, 0.0139, + 0.0200, 0.0200, 0.0139, 0.0139, + 0.0139, 0.0139, 0.0139, 0.0139, + 0.0139, 0.0139, + ] + # fmt: on + m_list = [ + np.pi * 7850 * w * ((odisc) ** 2 - (idisc) ** 2) + for w, odisc, idisc in zip(width, o_disc, i_disc) + ] + Id_list = [ + m / 12 * (3 * idisc**2 + 3 * odisc**2 + w**2) + for m, idisc, odisc, w in zip(m_list, i_disc, o_disc, width) + ] + Ip_list = [ + m / 2 * (idisc**2 + odisc**2) for m, idisc, odisc in zip(m_list, i_disc, o_disc) + ] + + disk_elements = [ + DiskElement( + n=n, + m=m, + Id=Id, + Ip=Ip, + ) + for n, m, Id, Ip in zip(n_list, m_list, Id_list, Ip_list) + ] + + # Bearing elements: + n_list = [12, 43] + u0 = 4 * np.pi * 1e-7 + n = 200 + A = 1e-4 + i0 = 1.0 + s0 = 1e-3 + alpha = 0.392 + Kp = 2 + Ki = 2 + Kd = 2 + k_amp = 1.0 + k_sense = 1.0 + bearing_elements = [ + MagneticBearingElement( + n=n_list[0], + g0=s0, + i0=i0, + ag=A, + nw=n, + alpha=alpha, + k_amp=k_amp, + k_sense=k_sense, + kp_pid=Kp, + kd_pid=Kd, + ki_pid=Ki, + ), + MagneticBearingElement( + n=n_list[1], + g0=s0, + i0=i0, + ag=A, + nw=n, + alpha=alpha, + k_amp=k_amp, + k_sense=k_sense, + kp_pid=Kp, + kd_pid=Kd, + ki_pid=Ki, + ), + ] + + return Rotor(shaft_elements, disk_elements, bearing_elements) From 8b09f806658bddfb16b1a0f1efe7744e185bfbdc Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Sun, 22 Sep 2024 16:53:10 -0300 Subject: [PATCH 07/14] Add example in magnetic_bearing_controller() --- ross/rotor_assembly.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/ross/rotor_assembly.py b/ross/rotor_assembly.py index 99842c374..c07449f9c 100644 --- a/ross/rotor_assembly.py +++ b/ross/rotor_assembly.py @@ -2136,7 +2136,30 @@ def magnetic_bearing_controller(self, magnetic_bearings, time_step, disp_resp): Examples -------- - + >>> import ross as rs + >>> rotor = rs.rotor_assembly.rotor_amb_example() + >>> size = 40001 + >>> speed = 1200.0 + >>> t = np.linspace(0, 1, size) + >>> dt = t[1] - t[0] + >>> node = [27, 29] + >>> mass = [10, 10] + >>> F = np.zeros((len(t), rotor.ndof)) + >>> for n, m in zip(node,mass): + ... F[:, 4 * n + 0] = m * np.cos((speed * t)) + ... F[:, 4 * n + 1] = (m-5) * np.sin((speed * t)) + >>> response = rotor.run_time_response(speed, F, t, method = "newmark") + Running direct method + >>> magnetic_bearings = [ + ... brg + ... for brg in rotor.bearing_elements + ... if isinstance(brg, MagneticBearingElement) + ... ] + >>> magnetic_force = rotor.magnetic_bearing_controller(magnetic_bearings, dt, response.yout[-1,:]) + >>> np.nonzero(magnetic_force)[0] + array([ 48, 49, 172, 173], dtype=int64) + >>> magnetic_force[np.nonzero(magnetic_force)[0]] + array([0.0070686 , 0.02656392, 0.00180106, 0.01577127]) """ offset = 0 From 70a33a6dd6c80f964959706bfec25a39490b2530 Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Sun, 22 Sep 2024 17:48:46 -0300 Subject: [PATCH 08/14] Add test_amb_controller() --- ross/tests/test_rotor_assembly.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ross/tests/test_rotor_assembly.py b/ross/tests/test_rotor_assembly.py index 8f8a27385..7598e8eed 100644 --- a/ross/tests/test_rotor_assembly.py +++ b/ross/tests/test_rotor_assembly.py @@ -2624,3 +2624,31 @@ def test_rotor_conical_frequencies(rotor_conical): ] ) assert_allclose(modal.wn, expected_wn, rtol=1e-5) + + +def test_amb_controller(): + # Test for the magnetic_bearing_controller method. + from ross.rotor_assembly import rotor_amb_example + + rotor = rotor_amb_example() + + speed = 1200 + t = np.linspace(0, 10, 40001) + node = [27, 29] + mass = [10, 10] + probes = [12, 43] + + F = np.zeros((len(t), rotor.ndof)) + for n, m in zip(node, mass): + F[:, 4 * n + 0] = m * np.cos((speed * t)) + F[:, 4 * n + 1] = (m - 5) * np.sin((speed * t)) + + response = rotor.run_time_response(speed, F, t, method="newmark") + + mean_response = [] + for ii in probes: + for jj in range(2): + mean_response.append(np.mean(response.yout[:, 4 * ii + jj])) + mean_max = np.max(np.array(mean_response)) + + assert_allclose(np.array(mean_max), np.array(7.31786978e-07), rtol=1e-6, atol=1e-6) From 4585c09936fd1f7c357b7036f3f650a4ce28d9ad Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Mon, 4 Nov 2024 08:22:31 -0300 Subject: [PATCH 09/14] Change in integrate_system variable --- ross/rotor_assembly.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ross/rotor_assembly.py b/ross/rotor_assembly.py index 18a055bd9..e17d9c17c 100644 --- a/ross/rotor_assembly.py +++ b/ross/rotor_assembly.py @@ -2156,7 +2156,7 @@ def magnetic_bearing_controller(self, magnetic_bearings, time_step, disp_resp): ... ] >>> magnetic_force = rotor.magnetic_bearing_controller(magnetic_bearings, dt, response.yout[-1,:]) >>> np.nonzero(magnetic_force)[0] - array([ 48, 49, 172, 173], dtype=int64) + array([ 48, 49, 172, 173]) >>> magnetic_force[np.nonzero(magnetic_force)[0]] array([0.0070686 , 0.02656392, 0.00180106, 0.01577127]) """ @@ -2283,7 +2283,7 @@ def integrate_system(self, speed, F, t, **kwargs): ) ) else: - magnetic_force = lambda time_step, disp_resp: 0 + magnetic_force = lambda time_step, disp_resp: np.zeros((self.ndof)) # Consider any additional RHS function (extra forces) add_to_RHS = kwargs.get("add_to_RHS") From e757884e65b67e7be052444ab199fea100ba94d2 Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Tue, 11 Feb 2025 15:36:21 -0300 Subject: [PATCH 10/14] Add rotation 45 deg in actuator --- ross/rotor_assembly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ross/rotor_assembly.py b/ross/rotor_assembly.py index e17d9c17c..282cddd39 100644 --- a/ross/rotor_assembly.py +++ b/ross/rotor_assembly.py @@ -2182,7 +2182,7 @@ def magnetic_bearing_controller(self, magnetic_bearings, time_step, disp_resp): elm.e0[idx_dofs] = err elm.control_signal[idx_dofs].append(signal_pid) - elm.magnetic_force[idx_dofs].append(magnetic_force[value_dofs]) + elm.magnetic_force[idx_dofs].append(magnetic_force[value_dofs]*np.sin(np.pi/4)) return magnetic_force From 647f5d4bebefff78d02f0f3dde1f8f786c589fef Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Sun, 23 Feb 2025 18:24:37 -0300 Subject: [PATCH 11/14] Change in the probe direction of magnetic_bearing_controller --- ross/rotor_assembly.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ross/rotor_assembly.py b/ross/rotor_assembly.py index 5697c73e6..0a6404433 100644 --- a/ross/rotor_assembly.py +++ b/ross/rotor_assembly.py @@ -2198,7 +2198,7 @@ def magnetic_bearing_controller(self, magnetic_bearings, time_step, disp_resp): >>> np.nonzero(magnetic_force)[0] array([ 48, 49, 172, 173]) >>> magnetic_force[np.nonzero(magnetic_force)[0]] - array([0.0070686 , 0.02656392, 0.00180106, 0.01577127]) + array([-0.00114497, 0.01361201, 0.00109872, 0.00670087]) """ offset = 0 @@ -2209,7 +2209,13 @@ def magnetic_bearing_controller(self, magnetic_bearings, time_step, disp_resp): for elm in magnetic_bearings: dofs = [self.number_dof * elm.n, self.number_dof * elm.n + 1] for idx_dofs, value_dofs in enumerate(dofs): - err = setpoint - disp_resp[value_dofs] + + if idx_dofs == 0: + disp_45 = disp_resp[value_dofs]*np.cos(np.pi/4) + else: + disp_45 = disp_resp[value_dofs]*np.sin(np.pi/4) + + err = setpoint - disp_45 P = elm.kp_pid * err elm.integral[idx_dofs] += elm.ki_pid * err * dt @@ -2217,7 +2223,7 @@ def magnetic_bearing_controller(self, magnetic_bearings, time_step, disp_resp): signal_pid = offset + P + elm.integral[idx_dofs] + D magnetic_force[value_dofs] = ( - elm.ki * signal_pid + elm.ks * disp_resp[value_dofs] + elm.ki * signal_pid + elm.ks * disp_45 ) elm.e0[idx_dofs] = err From 4e47fd7d69eb88f34b9c7e4b6fd99a59956a061d Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Sun, 23 Feb 2025 18:27:06 -0300 Subject: [PATCH 12/14] Change in the assert of test_amb_controller() --- ross/tests/test_rotor_assembly.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ross/tests/test_rotor_assembly.py b/ross/tests/test_rotor_assembly.py index 5d88ba0f6..0991b4fdb 100644 --- a/ross/tests/test_rotor_assembly.py +++ b/ross/tests/test_rotor_assembly.py @@ -2678,4 +2678,4 @@ def test_amb_controller(): mean_response.append(np.mean(response.yout[:, 4 * ii + jj])) mean_max = np.max(np.array(mean_response)) - assert_allclose(np.array(mean_max), np.array(7.31786978e-07), rtol=1e-6, atol=1e-6) + assert_allclose(np.array(mean_max), np.array(1.40899209e-07), rtol=1e-6, atol=1e-6) From dbfc85446bc33a81fe1f9d8f0b78de1ea6600571 Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Sun, 23 Feb 2025 18:40:23 -0300 Subject: [PATCH 13/14] Update of the array magnetic_force for pytest --- ross/rotor_assembly.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ross/rotor_assembly.py b/ross/rotor_assembly.py index 0a6404433..79f771cdc 100644 --- a/ross/rotor_assembly.py +++ b/ross/rotor_assembly.py @@ -2196,9 +2196,9 @@ def magnetic_bearing_controller(self, magnetic_bearings, time_step, disp_resp): ... ] >>> magnetic_force = rotor.magnetic_bearing_controller(magnetic_bearings, dt, response.yout[-1,:]) >>> np.nonzero(magnetic_force)[0] - array([ 48, 49, 172, 173]) + array([ 72, 73, 258, 259]) >>> magnetic_force[np.nonzero(magnetic_force)[0]] - array([-0.00114497, 0.01361201, 0.00109872, 0.00670087]) + array([ 0.07273389, 0.10095048, -0.08090672, -0.04073291]) """ offset = 0 From d19d91e8fd39b337a4a5a90bda0ce96a3f783a03 Mon Sep 17 00:00:00 2001 From: mcarolalb Date: Sun, 23 Feb 2025 19:03:22 -0300 Subject: [PATCH 14/14] Update examples to 6dof --- ross/rotor_assembly.py | 6 +++--- ross/tests/test_rotor_assembly.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ross/rotor_assembly.py b/ross/rotor_assembly.py index 79f771cdc..ff56d7e8e 100644 --- a/ross/rotor_assembly.py +++ b/ross/rotor_assembly.py @@ -2185,8 +2185,8 @@ def magnetic_bearing_controller(self, magnetic_bearings, time_step, disp_resp): >>> mass = [10, 10] >>> F = np.zeros((len(t), rotor.ndof)) >>> for n, m in zip(node,mass): - ... F[:, 4 * n + 0] = m * np.cos((speed * t)) - ... F[:, 4 * n + 1] = (m-5) * np.sin((speed * t)) + ... F[:, 6 * n + 0] = m * np.cos((speed * t)) + ... F[:, 6 * n + 1] = (m-5) * np.sin((speed * t)) >>> response = rotor.run_time_response(speed, F, t, method = "newmark") Running direct method >>> magnetic_bearings = [ @@ -2198,7 +2198,7 @@ def magnetic_bearing_controller(self, magnetic_bearings, time_step, disp_resp): >>> np.nonzero(magnetic_force)[0] array([ 72, 73, 258, 259]) >>> magnetic_force[np.nonzero(magnetic_force)[0]] - array([ 0.07273389, 0.10095048, -0.08090672, -0.04073291]) + array([-0.00114497, 0.01361201, 0.00109872, 0.00670087]) """ offset = 0 diff --git a/ross/tests/test_rotor_assembly.py b/ross/tests/test_rotor_assembly.py index 0991b4fdb..e25a1bcb5 100644 --- a/ross/tests/test_rotor_assembly.py +++ b/ross/tests/test_rotor_assembly.py @@ -2667,15 +2667,15 @@ def test_amb_controller(): F = np.zeros((len(t), rotor.ndof)) for n, m in zip(node, mass): - F[:, 4 * n + 0] = m * np.cos((speed * t)) - F[:, 4 * n + 1] = (m - 5) * np.sin((speed * t)) + F[:, 6 * n + 0] = m * np.cos((speed * t)) + F[:, 6 * n + 1] = (m - 5) * np.sin((speed * t)) response = rotor.run_time_response(speed, F, t, method="newmark") mean_response = [] for ii in probes: for jj in range(2): - mean_response.append(np.mean(response.yout[:, 4 * ii + jj])) + mean_response.append(np.mean(response.yout[:, 6 * ii + jj])) mean_max = np.max(np.array(mean_response)) assert_allclose(np.array(mean_max), np.array(1.40899209e-07), rtol=1e-6, atol=1e-6)