ross.MagneticBearingElement
Contents
ross.MagneticBearingElement#
- class ross.MagneticBearingElement(n, g0, i0, ag, nw, frequency=None, alpha=0.39269908, k_amp=1, k_sense=1, kp_pid=0, kd_pid=0, ki_pid=0, n_f=10000, controller_transfer_function=None, sensors_axis_rotation=0.78539816, tag=None, n_link=None, scale_factor=1, color='#355d7a', **kwargs)#
Magnetic Bearing Element.
This class represents an active magnetic bearing (AMB) modeled from its electromagnetic and control parameters. It automatically converts the physical parameters of the electromagnet and the controller (PID or custom transfer function) into equivalent stiffness and damping coefficients as functions of frequency.
If a transfer function is not supplied, the user must define the proportional, integral, and derivative gains of the PID controller, including the cutoff frequency of the derivative filter. The class also computes the transformation of the stiffness and damping matrices according to the magnetic pole angle.
- Parameters:
- nint
Node index where the magnetic bearing is mounted on the rotor.
- g0float
Nominal air gap (m).
- i0float or list of float
Bias current applied to the coils (A). Can be a scalar value or a list of two values for the x and y axes.
- agfloat
Effective pole area (m²).
- nwint or float
Number of turns per coil (windings).
- frequencyarray_like, optional
Frequency vector in rad/s used to evaluate the controller frequency response and build the equivalent stiffness and damping coefficients. If not provided, it is set automatically as a logarithmic vector between 10⁰ and 10⁴ rad/s.
- alphafloat, optional
Angular position of the magnetic pole relative to the rotor x axis (radians). Default is 0.39269908 (approximately 22.5°).
- k_ampfloat or list of float, optional
Power amplifier gain (V/A). Can be a scalar value or a list of two values, one for each axis. Default is 1.
- k_sensefloat or list of float, optional
Displacement sensor gain (V/m). Can be a scalar value or a list of two values, one for each axis. Default is 1.
- kp_pidfloat or int, optional
Proportional gain of the PID controller. Default is 0.
- kd_pidfloat or int, optional
Derivative gain of the PID controller. Default is 0.
- ki_pidfloat or int, optional
Integral gain of the PID controller. Default is 0.
- n_ffloat, optional
Cutoff frequency of the derivative low-pass filter (rad/s) used in the PID controller. Default is 10 000.
- controller_transfer_functioncontrol.TransferFunction, optional
Continuous-time transfer function that represents a custom controller associated with the AMB. When provided, it overrides the PID gains for the computation of the controller frequency response and the equivalent coefficients.
- sensors_axis_rotationfloat, optional
Angular rotation between the rotor x–y axes and the sensor/actuator axes (radians). This angle is used to transform the equivalent isotropic stiffness and damping into the anisotropic matrices in the rotor coordinates. Default is 0.78539816 (approximately 45°).
- tagstr, optional
Label used to identify the element in the rotor model.
- n_linkint, optional
Node connected to the bearing. If not specified, the bearing is considered grounded. Default is None.
- scale_factorfloat, optional
Scale factor for graphical representation. Default is 1.
- colorstr, optional
Color used for graphical representation. Default is “#355d7a”.
- **kwargs
Additional keyword arguments forwarded to the base class constructor.
- Attributes:
- g0float
Nominal air gap (m).
- i0float or numpy.ndarray
Bias current applied to the coils (A) in each controlled axis.
- agfloat
Effective pole area (m²).
- nwfloat
Number of turns per coil (windings).
- alphafloat
Magnetic pole angle relative to the rotor x axis (radians).
- k_ampnumpy.ndarray
Amplifier gains for each axis (V/A).
- k_sensenumpy.ndarray
Sensor gains for each axis (V/m).
- kp_pid, kd_pid, ki_pidfloat
PID controller gains.
- n_ffloat
Cutoff frequency of the derivative filter (rad/s).
- sensors_axis_rotationfloat
Rotation angle between rotor and sensor/actuator axes (radians).
- frequencynumpy.ndarray
Frequency vector in rad/s used to compute the equivalent stiffness and damping matrices.
- ksfloat
Negative electromagnetic stiffness constant obtained from the linearization of the magnetic force.
- kifloat
Electromagnetic current-to-force gain.
- kxx, kxy, kyx, kyynumpy.ndarray
Frequency-dependent stiffness coefficients in the rotor x–y coordinates (N/m).
- cxx, cxy, cyx, cyynumpy.ndarray
Frequency-dependent damping coefficients in the rotor x–y coordinates (N·s/m).
- controller_transfer_function_numnumpy.ndarray or None
Numerator coefficients of the custom controller transfer function, if provided.
- controller_transfer_function_dennumpy.ndarray or None
Denominator coefficients of the custom controller transfer function, if provided.
- A_c, B_c, C_c, D_cnumpy.ndarray or None
Discrete-time state-space matrices of the controller model obtained after discretization.
- x_clist of numpy.matrix or None
List with two state vectors (one for each AMB axis) used in the discrete-time controller update.
- control_signallist
Time history of the control current signals, stored as a list of pairs of lists, one pair for each time step.
- magnetic_force_xylist
Time history of the magnetic forces expressed in the rotor x–y coordinates.
- magnetic_force_vwlist
Time history of the magnetic forces expressed in the local pole coordinates.
See also
get_analog_controllerBuild or retrieve the analog controller transfer function.
build_controllerDiscretize the analog controller and initialize the internal state-space representation.
compute_pid_ambCompute the control force generated by the AMB controller for a single axis.
Notes
The electromagnetic coefficients ks and ki are computed following Schweitzer and Maslen, Magnetic Bearings: Theory, Design, and Application to Rotating Machinery, Springer, pages 69–80 and 343.
The frequency-dependent stiffness and damping coefficients are obtained from the real and imaginary parts of the closed-loop controller frequency response.
The same controller is assumed for both controlled axes.
The method get_analog_controller builds the continuous-time controller associated with the element, build_controller creates the discrete-time state-space representation, and compute_pid_amb uses this representation to compute the magnetic forces for time-domain simulations.
Examples
Create an AMB element using PID gains and inspect one of the equivalent stiffness coefficients:
>>> import ross as rs >>> n = 0 >>> g0 = 1e-3 >>> i0 = 1.0 >>> ag = 1e-4 >>> nw = 200 >>> alpha = 0.39269908 >>> kp_pid = 1.0 >>> kd_pid = 1.0 >>> k_amp = 1.0 >>> k_sense = 1.0 >>> mb = rs.MagneticBearingElement( ... n=n, g0=g0, i0=i0, ag=ag, nw=nw, alpha=alpha, ... kp_pid=kp_pid, kd_pid=kd_pid, k_amp=k_amp, k_sense=k_sense ... ) >>> mb.kxx[0] -4639.28...
Use a custom controller transfer function instead of PID gains:
>>> import control as ct >>> import numpy as np >>> C_s = ct.TransferFunction([1.0, 10.0], [1.0, 2.0, 3.0]) >>> mb_custom = rs.MagneticBearingElement( ... n=0, g0=1e-3, i0=1.0, ag=1e-4, nw=200, ... controller_transfer_function=C_s ... ) >>> isinstance(mb_custom.get_analog_controller(), ct.TransferFunction) True
Methods
- C(frequency)#
Damping matrix for an instance of a bearing element.
This method returns the damping matrix for an instance of a bearing element.
- Parameters:
- frequencyfloat
The excitation frequency (rad/s).
- Returns:
- Cnp.ndarray
A 3x3 matrix of floats containing the cxx, cxy, cyx, cyy, and czz values (N*s/m).
Examples
>>> bearing = bearing_example() >>> bearing.C(0) array([[200., 0., 0.], [ 0., 150., 0.], [ 0., 0., 50.]])
- G()#
Gyroscopic matrix for an instance of a bearing element.
This method returns the mass matrix for an instance of a bearing element.
- Returns:
- Gnp.ndarray
A 3x3 matrix of floats.
Examples
>>> bearing = bearing_example() >>> bearing.G() array([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]])
- K(frequency)#
Stiffness matrix for an instance of a bearing element.
This method returns the stiffness matrix for an instance of a bearing element.
- Parameters:
- frequencyfloat
The excitation frequency (rad/s).
- Returns:
- Knp.ndarray
A 3x3 matrix of floats containing the kxx, kxy, kyx, kyy and kzz values (N/m).
Examples
>>> bearing = bearing_example() >>> bearing.K(0) array([[1000000., 0., 0.], [ 0., 800000., 0.], [ 0., 0., 100000.]])
- M(frequency)#
Mass matrix for an instance of a bearing element.
This method returns the mass matrix for an instance of a bearing element.
- Parameters:
- frequencyfloat
The excitation frequency (rad/s).
- Returns:
- Mnp.ndarray
Mass matrix (kg).
Examples
>>> bearing = bearing_example() >>> bearing.M(0) array([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]])
- __init__(n, g0, i0, ag, nw, frequency=None, alpha=0.39269908, k_amp=1, k_sense=1, kp_pid=0, kd_pid=0, ki_pid=0, n_f=10000, controller_transfer_function=None, sensors_axis_rotation=0.78539816, tag=None, n_link=None, scale_factor=1, color='#355d7a', **kwargs)#
- build_controller(dt)#
Discretize the analog controller and initialize its state-space representation.
This method retrieves the continuous-time (analog) controller from the get_analog_controller() method, discretizes it using the Tustin (bilinear) transformation for the specified sampling period, converts it to a state-space representation, and initializes the internal controller states for the two active magnetic bearing (AMB) axes (x and y).
- Parameters:
- dtfloat
Sampling period in seconds used to discretize the controller.
See also
get_analog_controllerBuilds or returns the analog controller transfer function.
compute_pid_ambComputes the control force generated by the AMB controller.
Notes
The controller is discretized using control.sample_system() with the method set to “tustin”.
The resulting discrete-time controller is represented in state-space form using control.ss().
This method must be called before executing any function that updates the controller states, such as compute_pid_amb().
Examples
>>> import ross as rs >>> mb = rs.MagneticBearingElement( ... n=0, g0=1e-3, i0=1.0, ag=1e-4, nw=200, ... kp_pid=1.0, kd_pid=0.1, ki_pid=0.5, n_f=1e4 ... ) >>> mb.build_controller(dt=1e-3) >>> mb.A_c.shape[0] == mb.x_c[0].shape[0] True
- compute_pid_amb(current_offset, setpoint, disp, dof_index)#
Compute AMB control force for one axis using the discrete controller.
This routine evaluates the discrete-time controller output for the selected degree of freedom (x or y) and converts it to the corresponding magnetic force. The controller must have been previously discretized and initialized with build_controller so that the internal state-space matrices and state vectors are available.
The calculation follows: 1) Compute the control output for the current error
u = C_c @ x_c[dof_index] + D_c * error, where error = setpoint - disp.
Update the controller state x_c[dof_index] = A_c @ x_c[dof_index] + B_c * error.
Form the coil signal signal_pid = current_offset + u.
Map current to force F = ki * signal_pid + ks * disp.
- Parameters:
- current_offsetfloat
Static offset added to the controller signal (for example, bias current).
- setpointfloat
Reference position for the controlled axis (usually zero).
- dispfloat
Measured displacement at the controlled axis.
- dof_indexint
Axis selector within the AMB element: 0 for x, 1 for y.
- Returns:
- float
Magnetic force for the selected AMB axis.
Notes
build_controller(dt) must be called beforehand; this method expects the attributes A_c, B_c, C_c, D_c and the list x_c to be initialized.
The electromagnetic coefficients ki (current-to-force gain) and ks (negative stiffness) must be defined in the element.
This method appends the latest control signal to self.control_signal[-1][dof_index]. Ensure that self.control_signal has a trailing item shaped like [[], []] (one list per axis) before the first call in a new time step.
Examples
>>> import ross as rs >>> import numpy as np >>> mb = rs.MagneticBearingElement( ... n=0, g0=1e-3, i0=1.0, ag=1e-4, nw=200, ... kp_pid=1.0, ki_pid=5.0, kd_pid=0.01, n_f=1e4 ... ) >>> mb.build_controller(dt=1e-3) >>> # start a new logging bucket for this time step (x and y) >>> mb.control_signal.append([[], []]) >>> # compute force for x-axis given a small measured displacement >>> force_x = mb.compute_pid_amb( ... current_offset=0.0, setpoint=0.0, disp=2e-4, dof_index=0 ... ) >>> isinstance(force_x, float) True
- dof_local_index()#
Get the local index for a element specific degree of freedom.
- Returns:
- local_index: namedtupple
A named tuple containing the local index.
Examples
>>> # Example using BearingElement >>> from ross.bearing_seal_element import bearing_example >>> bearing = bearing_example() >>> bearing.dof_local_index() LocalIndex(x_0=0, y_0=1, z_0=2)
- dof_mapping()#
Degrees of freedom mapping.
Returns a dictionary with a mapping between degree of freedom and its index.
- Returns:
- dof_mappingdict
A dictionary containing the degrees of freedom and their indexes.
Examples
The numbering of the degrees of freedom for each node.
Being the following their ordering for a node:
x_0 - horizontal translation y_0 - vertical translation z_0 - axial translation
>>> bearing = bearing_example() >>> bearing.dof_mapping() {'x_0': 0, 'y_0': 1, 'z_0': 2}
- format_table(frequency=None, coefficients=None, frequency_units='rad/s', stiffness_units='N/m', damping_units='N*s/m', mass_units='kg')#
Return frequency vs coefficients in table format.
- Parameters:
- frequencyarray, pint.Quantity, optional
Array with frequencies (rad/s). Default is 5 values from min to max frequency.
- coefficientslist, str, optional
List or str with the coefficients to include. Defaults is a list of stiffness and damping coefficients.
- frequency_unitsstr, optional
Frequency units. Default is rad/s.
- stiffness_unitsstr, optional
Stiffness units. Default is N/m.
- damping_unitsstr, optional
Damping units. Default is N*s/m.
- mass_unitsstr, optional
Mass units. Default is kg.
- Returns:
- tablePrettyTable object
Table object with bearing coefficients to be printed.
- classmethod from_table(n, file, sheet_name=0, tag=None, n_link=None, scale_factor=1, color='#355d7a')#
Instantiate a bearing using inputs from an Excel table.
A header with the names of the columns is required. These names should match the names expected by the routine (usually the names of the parameters, but also similar ones). The program will read every row bellow the header until they end or it reaches a NaN.
- Parameters:
- nint
The node in which the bearing will be located in the rotor.
- filestr
Path to the file containing the bearing parameters.
- sheet_nameint or str, optional
Position of the sheet in the file (starting from 0) or its name. If none is passed, it is assumed to be the first sheet in the file.
- tagstr, optional
A tag to name the element. Default is None.
- n_linkint, optional
Node to which the bearing will connect. If None the bearing is connected to ground. Default is None.
- scale_factorfloat, optional
The scale factor is used to scale the bearing drawing. Default is 1.
- colorstr, optional
A color to be used when the element is represented. Default is ‘#355d7a’ (Cardinal).
- Returns:
- bearingrs.BearingElement
A bearing object.
Examples
>>> import os >>> file_path = os.path.dirname(os.path.realpath(__file__)) + '/tests/data/bearing_seal_si.xls' >>> BearingElement.from_table(0, file_path, n_link=1) BearingElement(n=0, n_link=1, kxx=[1.379...
- get_analog_controller()#
Return the continuous-time (analog) controller transfer function.
This method builds or retrieves the analog controller C(s) associated with the magnetic bearing element. If a custom controller transfer function has been provided, it will be returned directly. Otherwise, the method constructs a PID controller with a low-pass filter applied to the derivative term, expressed as:
C(s) = Kp + Ki / s + Kd * s * (1 / (1 + (1 / n_f) * s))
- where:
Kp is the proportional gain
Ki is the integral gain
Kd is the derivative gain
n_f is the cutoff frequency of the derivative filter
- Returns:
- control.TransferFunction
Continuous-time controller transfer function C(s).
See also
build_controllerDiscretizes the analog controller and initializes its state matrices.
compute_pid_ambUses the controller to compute active magnetic bearing control forces.
Notes
If both a custom transfer function and PID gains are defined, the custom transfer function takes precedence.
The Laplace variable ‘s’ is obtained from MagneticBearingElement.s.
The output of this method is used in build_controller() to generate the corresponding discrete-time (sampled) version of the controller.
Examples
>>> import control as ct >>> import ross as rs >>> mb = rs.MagneticBearingElement( ... n=0, g0=1e-3, i0=1.0, ag=1e-4, nw=200, ... kp_pid=1.0, ki_pid=10.0, kd_pid=0.01, n_f=1e4 ... ) >>> C_s = mb.get_analog_controller() >>> isinstance(C_s, ct.TransferFunction) True
>>> # Example with custom transfer function >>> mb.controller_transfer_function_num = [1, 5] >>> mb.controller_transfer_function_den = [1, 2, 3] >>> C_custom = mb.get_analog_controller() >>> C_custom.num[0][0] array([1, 5])
- get_class_name_prefix(index=None)#
Extract prefix of the class name preceding ‘Element’, insert spaces before uppercase letters, and append an index number at the end.
- Parameters:
- indexint, optional
The index number to append at the end of the resulting string. Default is None.
- Returns:
- prefixstr
The processed class name prefix.
Examples
>>> # Example using BearingElement >>> from ross.bearing_seal_element import bearing_example >>> bearing = bearing_example() >>> bearing.get_class_name_prefix() 'Bearing'
- classmethod get_subclasses()#
- classmethod load(file)#
- plot(coefficients=None, frequency_units='rad/s', stiffness_units='N/m', damping_units='N*s/m', mass_units='kg', fig=None, **kwargs)#
Plot coefficient vs frequency.
- Parameters:
- coefficientslist, str
List or str with the coefficients to plot.
- frequency_unitsstr, optional
Frequency units. Default is rad/s.
- stiffness_unitsstr, optional
Stiffness units. Default is N/m.
- damping_unitsstr, optional
Damping units. Default is N*s/m.
- mass_unitsstr, optional
Mass units. Default is kg.
- **kwargsoptional
Additional key word arguments can be passed to change the plot layout only (e.g. width=1000, height=800, …). *See Plotly Python Figure Reference for more information.
- Returns:
- figPlotly graph_objects.Figure()
The figure object with the plot.
- classmethod read_toml_data(data)#
Read and parse data stored in a .toml or .json file.
Overrides the base Element method to pass extra saved keys (e.g. pre-computed coefficients) as kwargs to the constructor. This allows subclasses to skip expensive computation when coefficients are already available from a saved file.
- Parameters:
- datadict
Dictionary obtained from toml.load() or json.load().
- Returns:
- The element object.
- save(file)#
Save the element in a .toml or .json file.
This function will save the element to a .toml or .json file. The file will have all the argument’s names and values that are needed to reinstantiate the element.
- Parameters:
- filestr, pathlib.Path
The name of the file the element will be saved in. The format is determined by the file extension (.toml or .json).
Examples
>>> # Example using DiskElement >>> from tempfile import tempdir >>> from pathlib import Path >>> from ross.disk_element import disk_example >>> # create path for a temporary file >>> file = Path(tempdir) / 'disk.toml' >>> disk = disk_example() >>> disk.save(file)
- summary()#
Present a summary for the element.
A pandas series with the element properties as variables.
- Returns:
- A pandas series.
Examples
>>> # Example using DiskElement >>> from ross.disk_element import disk_example >>> disk = disk_example() >>> disk.summary() n 0 n_l 0 n_r 0...
- classmethod table_to_toml(n, file)#
Convert bearing parameters to toml.
Convert a table with parameters of a bearing element to a dictionary ready to save to a toml file that can be later loaded by ross.
- Parameters:
- nint
The node in which the bearing will be located in the rotor.
- filestr
Path to the file containing the bearing parameters.
- Returns:
- datadict
A dict that is ready to save to toml and readable by ross.
Examples
>>> import os >>> file_path = os.path.dirname(os.path.realpath(__file__)) + '/tests/data/bearing_seal_si.xls' >>> BearingElement.table_to_toml(0, file_path) {'n': 0, 'kxx': array([...
Attributes
s