MockControlClosedLoop¶
- class lsst.ts.m2com.MockControlClosedLoop(is_mirror: bool = False)¶
Bases:
objectMock closed-loop control.
Parameters¶
- is_mirror
bool, optional Is mirror or not. If not, the surrogate is applied. (the default is False)
Attributes¶
- is_running
bool The closed-loop control is running or not.
- temperature
dict Temperature of mirror in degree C.
- axial_forces
dict Forces of the axial actuators in Newton.
- tangent_forces
dict Forces of the tangent actuators in Newton.
- hardpoints
list List of the hardpoints. There are 6 actuators. The first three are the axial actuators and the latter three are the tangent links.
- disp_hardpoint_home
list Displacement of the hardpoints at the home position. The unit is meter.
- control_loop
MockControlLoop Mock control loop with the force control algorithm.
Methods Summary
apply_forces(force_axial, force_tangent)Apply the actuator forces.
calc_cmd_delay_filter_params([is_mirror, ...])Calculate the command delay filter parameters (or more clearly, the numerator of the transfer function).
calc_cmd_prefilter_params([numerator, ...])Calculate the command pre-filter parameters in biquadratic filters.
Calculate the force control filter parameters in biquadratic filters.
calc_hp_comp_matrix(location_axial_actuator, ...)Calculate the hardpoint compensation matrix.
Calculate the kinetic decoupling matrix.
calc_look_up_forces([lut_angle, ...])Calculate look-up table (LUT) forces using current system state (position and temperature).
Calculate the temperature inversion matrix.
calculate_rigid_body_xy(radius, ...)Calculate the rigid body (x, y) position.
get_active_actuators(hardpoints_axial, ...)Get the active actuators.
Get the location of axial actuators.
Get the location of tangent actuators.
get_demanded_force([applied_force_axial, ...])Get the demanded force in Newton.
Get the data of force balance system.
Get the total net forces in Newton.
Get the total net moments in Newton * meter.
Get the radius of the tangential actuators.
handle_forces(is_in_position[, plant, ...])Handle forces and update the hardpoint correction and measured forces.
Calculate the rigid body position based on the hardpoint displacements.
is_actuator_force_out_limit([...])The actuator force is out of limit or not.
Cell temperature is high or not.
load_file_cell_geometry(filepath)Load the file of cell geometry.
load_file_lut(filepath)Load the look-up table (LUT) files.
load_file_stiffness(filepath)Load the file of stiffness matrix.
Reset the force offsets.
Calculate the actuator displacements based on the rigid body position.
Set the hardpoint compensation matrix.
Set the kinetic decoupling matrix.
set_measured_forces(force_axial, force_tangent)Set the measured actuator forces.
Simulate the temperature change and update the internal value.
Transfer function to the biquadratic filters.
update_hardpoints(hardpoints)Update the hardpoints and related internal parameters.
Methods Documentation
- apply_forces(force_axial: list[float] | ndarray[tuple[int, ...], dtype[float64]], force_tangent: list[float] | ndarray[tuple[int, ...], dtype[float64]]) None¶
Apply the actuator forces.
Parameters¶
- force_axial
listornumpy.ndarray Force of the axial actuators in Newton.
- force_tangent
listornumpy.ndarray Force of the tangent actuators in Newton.
Raises¶
RuntimeErrorWhen the maximum force limits reached.
- force_axial
- static calc_cmd_delay_filter_params(is_mirror: bool = True, control_frequency: float = 20.0, bypass_delay: bool = False, num_degree: int = 5) list[float]¶
Calculate the command delay filter parameters (or more clearly, the numerator of the transfer function).
Notes¶
Translate the calculation from the Create_Filter_Params.m in ts_mtm2_matlab_tools.
For a transfer function, H(z), if the numerator is [1, 3, 3] and the denominator is [1, 2, 1], it will be:
H(z) = (z^2 + 3 * z + 3) / (z^2 + 2 * z + 1)
Since the denominator of transfer function is the demanded force change here, the linear transfer ([1.0]) is applied. Therefore, we only care about the delay of command as the output.
Parameters¶
- is_mirror
bool, optional Is mirror or not. If not, the surrogate is applied. (the default is True)
- control_frequency
float, optional Frequency of the control loop in Hz. (the default is 20.0)
- bypass_delay
bool, optional Bypass the command delay or not. (the default is False)
- num_degree
int, optional Number of the degree in the transfer function. (the default is 5)
Returns¶
- numerator_transfer_function
list Numerator of the transfer function from the high degree to low degree.
- is_mirror
- static calc_cmd_prefilter_params(numerator: list[float] | None = None, denominator: list[float] | None = None) tuple[float, numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.float64]]]¶
Calculate the command pre-filter parameters in biquadratic filters.
Notes¶
Translate the calculation from the Create_Filter_Params.m in ts_mtm2_matlab_tools.
Currently, pre-filter is a pass-through filter.
Parameters¶
- numerator
listor None, optional Numerator polynomial coefficients of the transfer function. If None, the linear transfer is assumed (aka. [1.0]). (the default is None)
- denominator
listor None, optional Denominator polynomial coefficients of the transfer function. If None, the linear transfer is assumed (aka. [1.0]). (the default is None)
Returns¶
floatGain.
listCoefficients of the command pre-filter parameters.
- numerator
- static calc_force_control_filter_params(is_mirror: bool = True, numerator: list[float] | None = None, denominator: list[float] | None = None) tuple[float, numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.float64]]]¶
Calculate the force control filter parameters in biquadratic filters.
Notes¶
Translate the calculation from the Create_Filter_Params.m in ts_mtm2_matlab_tools.
Parameters¶
- is_mirror
bool, optional Is mirror or not. If not, the surrogate is applied. (the default is True)
- numerator
listor None, optional Numerator polynomial coefficients of the transfer function. If None, the linear transfer is assumed (aka. [1.0]). (the default is None)
- denominator
listor None, optional Denominator polynomial coefficients of the transfer function. If None, the linear transfer is assumed (aka. [1.0]). (the default is None)
Returns¶
floatGain.
- coefficients
list Coefficients of the force control filter parameters.
- is_mirror
- static calc_hp_comp_matrix(location_axial_actuator: list[list], hardpoints_axial: list[int], hardpoints_tangent: list[int]) tuple[numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.float64]], numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.float64]]]¶
Calculate the hardpoint compensation matrix.
Notes¶
<Axial actuators>
Translate the calculation from the CalcHPFCInfMat.m in ts_mtm2_matlab_tools.
The axial hardpoint compensation matrix (M) fulfills:
M * (x_hp, y_hp, 1) = (x_nhp, y_nhp, 1)
x_hp: x-position of hardpoint y_hp: y-position of hardpoint x_nhp: x-position of non-hardpoint y_nhp: y-position of non-hardpoint
The idea is to make the x-moment amd y-moment keep the same when distributes the force of axial hardpoints to other axial actuators. It is the same idea for tangential actuators with z-moment.
<Tangent links>
Assume the hardpoints are A1, A3, and A5. If they were active, the z-moment would be: 3 * fm * mirror_radius, where fm = (f1 + f3 + f5) / 3.
For the active tagent links: A2, A4, and A5 to maintain this z-moment while keeping the hardpoints to be passive, we have:
f2 = -(f5 - fm) + fm = 2 * fm - f5 = 2 / 3 * (f1 + f3 + f5) - f5 f4 = -(f1 - fm) + fm = 2 * fm - f1 = 2 / 3 * (f1 + f3 + f5) - f1 f6 = -(f3 - fm) + fm = 2 * fm - f3 = 2 / 3 * (f1 + f3 + f5) - f3
Then, we have:
f2 = 2 / 3 * f1 + 2 / 3 * f3 - 1 / 3 * f5 f4 = -1 / 3 * f1 + 2 / 3 * f3 + 2 / 3 * f5 f6 = 2 / 3 * f1 - 1 / 3 * f3 + 2 / 3 * f5
In the matrix form, it will be:
(f2, f4, f6).T = M * (f1, f3, f5).T
If the hardpoints were A2, A4, A6, we would have:
(f1, f3, f5).T = M ^ (-1) * (f2, f4, f6).T
Parameters¶
- location_axial_actuator
list Location of the axial actuators: (x, y). This should be a 72 x 2 matrix.
- hardpoints_axial
list Three axial hardpoints. The order is from low to high, e.g. [5, 15, 25].
- hardpoints_tangent
list Three tangential hardpoints. This can only be [72, 74, 76] or [73, 75, 77]. The order is from low to high.
Returns¶
- hd_comp_axial
numpy.ndarray Axial hardpoint compensation matrix.
- hd_comp_tangent
numpy.ndarray Tangential hardpoint compensation matrix.
- location_axial_actuator
- static calc_kinetic_decoupling_matrix(location_axial_actuator: list[list], hardpoints_axial: list[int], hardpoints_tangent: list[int], stiffness_matrix: ndarray[tuple[int, ...], dtype[float64]]) ndarray[tuple[int, ...], dtype[float64]]¶
Calculate the kinetic decoupling matrix.
Notes¶
Translate the calculation from the CalcHPFCInfMat.m in ts_mtm2_matlab_tools.
The unit of the element is the motor step (could be fraction, row) per Newton (column). This matrix is used to multiply with the desired actuator’s force changes to get the related amounts of motor’s step changes.
delta_force = M * delta_step => M^-1 = kdc to have: delta_step = kdc * delta_force
Parameters¶
- location_axial_actuator
list Location of the axial actuators: (x, y). This should be a 72 x 2 matrix.
- hardpoints_axial
list Three axial hardpoints. The order is from low to high, e.g. [5, 15, 25].
- hardpoints_tangent
list Three tangential hardpoints. This can only be [72, 74, 76] or [73, 75, 77]. The order is from low to high.
- stiffness_matrix
numpy.ndarray Stiffness matrix of M2 mirror or surrogate.
Returns¶
numpy.ndarrayKinetic decoupling matrix.
- location_axial_actuator
- calc_look_up_forces(lut_angle: float | None = None, enable_lut_temperature: bool | None = None) None¶
Calculate look-up table (LUT) forces using current system state (position and temperature).
Parameters¶
- lut_angle
floator None, optional Angle used to calculate the LUT forces of gravity component. If None, bypass the calculation. (the default is None)
- enable_lut_temperature
boolor None, optional Enable the temperature LUT calculation or not. If None, bypass the calculation. (the default is None)
- lut_angle
- static calc_temp_inv_matrix() ndarray[tuple[int, ...], dtype[float64]]¶
Calculate the temperature inversion matrix.
Based on the “LSST_M2_temperature_sensors_20171102.pdf”. The sensor map is at “doc/figure/temperature_sensor_map.jpg”.
Radial gradient: T(r) = Tr * r / R X gradient: T(x) = Tx * x / R = Tx * r * cos(theta) / R Y gradient: T(y) = Ty * y / R = Ty * r * sin(theta) / R Uniform bias: T(u) = Tu
The matrix is: [r/R, r/R * cos(theta), r/R * sin(theta), 1], and we have: matrix * [Tr, Tx, Ty, Tu].T = [T1, T2, …, T12].T
Returns¶
numpy.ndarrayTemperature inversion matrix.
- static calculate_rigid_body_xy(radius: float, tangent_hardpoint_displacement: list[float], tangent_hardpoint_location: list[float]) tuple[float, float, numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.float64]]]¶
Calculate the rigid body (x, y) position.
Notes¶
This is part of the calculation in HardPointToRigidBody.vi in ts_mtm2.
Parameters¶
- radius
float Radius of the cell in meter.
- tangent_hardpoint_displacement
list Displacement of the 3 tangent hardpoints in meter.
- tangent_hardpoint_location
list Location of the 3 tangent hardpoints in radian.
Returns¶
- mean_x
float X position in meter.
- mean_y
float Y position in meter.
- delta_xy_tangent_hardpoint
numpy.ndarray Delta (x, y) position compared with the mean (x, y) in meter.
- radius
- static get_active_actuators(hardpoints_axial: list[int], hardpoints_tangent: list[int]) tuple[list[int], list[int]]¶
Get the active actuators.
Parameters¶
- hardpoints_axial
list Three axial hardpoints. The order is from low to high, e.g. [5, 15, 25].
- hardpoints_tangent
list Three tangential hardpoints. This can only be [72, 74, 76] or [73, 75, 77]. The order is from low to high.
Returns¶
- active_actuators_axial
list Axial active actuators.
- active_actuators_tangent
list Tangential active actuators.
Raises¶
ValueErrorIf the tangential hardpoints are wrong.
- hardpoints_axial
- get_actuator_location_axial() list¶
Get the location of axial actuators.
Returns¶
listLocation (x, y) of the axial actuators in meter.
- get_actuator_location_tangent() list¶
Get the location of tangent actuators.
Returns¶
listLocation of the tangential actuators in degree.
- get_demanded_force(applied_force_axial: ndarray[tuple[int, ...], dtype[float64]] | None = None, applied_force_tangent: ndarray[tuple[int, ...], dtype[float64]] | None = None) ndarray[tuple[int, ...], dtype[float64]]¶
Get the demanded force in Newton.
Parameters¶
- applied_force_axial
numpy.ndarrayorNone, optional Axial forces to apply in Newton. If
Noneuse current setup. (the default is None.)- applied_force_tangent
numpy.ndarrayorNone, optional Tangent forces to apply in Newton. If
Noneuse current setup. ( the default is None.)
Returns¶
numpy.ndarrayArray with the combined total force per actuator in Newton.
- applied_force_axial
- get_force_balance() dict¶
Get the data of force balance system. This contains the net forces (in Newton) and net moments (in Newton * meter).
Returns¶
- force_balance
dict Data of the force balance system.
- force_balance
- get_net_forces_total() dict¶
Get the total net forces in Newton.
Returns¶
dictTotal net forces in Newton.
- get_net_moments_total() dict¶
Get the total net moments in Newton * meter.
Returns¶
dictTotal net moments in Newton * meter.
- get_radius() float¶
Get the radius of the tangential actuators.
Returns¶
floatRadius of the tangential actuators in meter.
- handle_forces(is_in_position: bool, plant: MockPlant | None = None, steps_hardpoints: ndarray[tuple[int, ...], dtype[int64]] | None = None) bool¶
Handle forces and update the hardpoint correction and measured forces.
Parameters¶
- is_in_position
bool Mirror is in position or not.
- plant
MockPlantor None Plant model. If not None, the movement of plant model will be applied.
- steps_hardpoints
numpy.ndarray[int] or None Hardpoint steps of the rigid body movement. (the default is None)
Returns¶
- in_position
bool M2 assembly is in position or not.
- is_in_position
- static hardpoint_to_rigid_body(location_axial_actuator: list[list], location_tangent_link: list[float], radius: float, hardpoints: list[int], disp_hardpoint_current: list[float], disp_hardpoint_home: list[float]) tuple[float, float, float, float, float, float]¶
Calculate the rigid body position based on the hardpoint displacements.
Notes¶
Translate the calculation from the HardPointToRigidBody.vi in ts_mtm2.
Parameters¶
- location_axial_actuator
list [list] Location of the axial actuators: (x, y) in meter. This should be a (NUM_ACTUATOR - NUM_TANGENT_LINK) x 2 matrix.
- location_tangent_link
list Location of the tangent links in degree. This should be a 1 x NUM_TANGENT_LINK array.
- radius
float Radius of the cell in meter.
- hardpoints
list Six hardpoints. The order is from low to high.
- disp_hardpoint_current
list Six current hardpoint displacements. The unit is meter.
- disp_hardpoint_home
list Six hardpoint displacements at the home position. The unit is meter.
Returns¶
- x
float X position in meter.
- y
float Y position in meter.
- z
float Z position in meter.
- rx
float X rotator in radian.
- ry
float Y rotator in radian.
- rz
float Z rotator in radian.
- location_axial_actuator
- is_actuator_force_out_limit(applied_force_axial: ndarray[tuple[int, ...], dtype[float64]] | None = None, applied_force_tangent: ndarray[tuple[int, ...], dtype[float64]] | None = None, use_measured_force: bool = False) tuple[bool, list, list]¶
The actuator force is out of limit or not.
Notes¶
Remove the ‘use_measured_force’ after we implement the forward modeling in the control algorithm. At that time, the measured force should be consistent with the demanded force (with the consideration of hardpoint correction).
Parameters¶
- applied_force_axial
numpy.ndarrayorNone, optional Axial forces to apply in Newton. If
Noneuse current setup. (the default is None.)- applied_force_tangent
numpy.ndarrayorNone, optional Tangent forces to apply in Newton. If
Noneuse current setup. ( the default is None.)- use_measured_force
bool, optional Use the measured force to compare with the limit. (the default is False)
Returns¶
boolTrue if the actuator force is out of limit. Otherwise, False.
listTriggered retracted limit switches.
listTriggered extended limit switches.
- applied_force_axial
- is_cell_temperature_high() bool¶
Cell temperature is high or not.
Returns¶
boolTrue if the cell temperature is high. Otherwise, False.
- load_file_cell_geometry(filepath: Path) None¶
Load the file of cell geometry.
Parameters¶
- filepath
pathlib.PosixPath File path of cell geometry.
- filepath
- load_file_lut(filepath: Path) None¶
Load the look-up table (LUT) files.
Parameters¶
- filepath
pathlib.PosixPath File path of LUT directory.
- filepath
- load_file_stiffness(filepath: Path) None¶
Load the file of stiffness matrix.
Parameters¶
- filepath
pathlib.PosixPath File path of stiffness matrix.
- filepath
- reset_force_offsets() None¶
Reset the force offsets.
This will put the applied force to be zero.
- static rigid_body_to_actuator_displacement(location_axial_actuator: list[list], location_tangent_link: list[float], radius: float, dx: float, dy: float, dz: float, drx: float, dry: float, drz: float) ndarray[tuple[int, ...], dtype[float64]]¶
Calculate the actuator displacements based on the rigid body position.
Notes¶
Translate the calculation from the RigidBodyToActuatorDisplacement.vi in ts_mtm2. For the “radius”, the original developer had the following comment:
An average of 5 of the 6 tangent location radius from the center of the M2 cell which is to be used by the rigid body to displacement calculation. Technically, it is not the B-ring radius and this should be changed in the future.
Parameters¶
- location_axial_actuator
list [list] Location of the axial actuators: (x, y) in meter. This should be a (NUM_ACTUATOR - NUM_TANGENT_LINK) x 2 matrix.
- location_tangent_link
list Location of the tangent links in degree. This should be a 1 x NUM_TANGENT_LINK array.
- radius
float Radius of the cell in meter.
- dx
float Delta x position in meter.
- dy
float Delta y position in meter.
- dz
float Delta z position in meter.
- drx
float Delta x rotator in radian.
- dry
float Delta y rotator in radian.
- drz
float Delta z rotator in radian.
Returns¶
numpy.ndarrayAll actuator displacements in meter.
- location_axial_actuator
- set_hardpoint_compensation() None¶
Set the hardpoint compensation matrix.
- set_kinetic_decoupling_matrix() None¶
Set the kinetic decoupling matrix.
- set_measured_forces(force_axial: ndarray[tuple[int, ...], dtype[float64]], force_tangent: ndarray[tuple[int, ...], dtype[float64]]) None¶
Set the measured actuator forces.
Parameters¶
- force_axial
numpy.ndarray Axial force in Newton.
- force_tangent
numpy.ndarray Tangential force in Newton.
Raises¶
ValueErrorWhen the input dimensions of forces are wrong.
- force_axial
- simulate_temperature_and_update(temperature_rms: float = 0.05, max_temperature: float = 28.0, min_temperature: float = 0.0) None¶
Simulate the temperature change and update the internal value.
Parameters¶
- temperature_rms
float, optional Temperature rms variation in degree C. (the default is 0.05)
- max_temperature
float, optional Maximum temperature in degree C. (the default is 28.0)
- min_temperature
float, optional Minimum temperature in degree C. (the default is 0.0)
- temperature_rms
- static transfer_function_to_biquadratic_filter(numerator: list[float], denominator: list[float], num_stage: int = 8) tuple[float, numpy.ndarray[tuple[int, ...], numpy.dtype[numpy.float64]]]¶
Transfer function to the biquadratic filters.
Notes¶
Translate the calculation from the bqd.m and sos2pqd.m in ts_mtm2_matlab_tools.
The reference is: https://en.wikipedia.org/wiki/Digital_biquad_filter
Compact biquadratic format:
1 + b11 z^-1 + b21 z^-2 1 + b12 z^-1 + b22 z^-2
- H(z) = gain * (———————–) (———————–) …
1 + a11 z^-1 + a21 z^-2 1 + a12 z^-1 + a22 z^-2
1 + b1N z^-1 + b2N z^-2
- (———————–)
1 + a1N z^-1 + a2N z^-2
Format of the coefficent output is: [a11 a21 b11 b21 a12 a22 b12 b22 … a1N a2N b1N b2N]
Parameters¶
- numerator
list Numerator polynomial coefficients of the transfer function.
- denominator
list Denominator polynomial coefficients of the transfer function.
- num_stage
int, optional Number of the stage of biquadratic filters. (the default is 8)
Returns¶
- gain
float Gain.
- coefficients
list Coefficients of the biquadratic filters.
- is_mirror