This is the M2 control system.
The available features are:
- fpga: Run the application with the use of the NI FPGA dynamic library.
- realtime: Run the application with the realtime feature (in Linux only).
Note: When doing the cargo check, make sure to check each feature under the required software/hardware requirement.
You can develop the code under the Windows, Mac, and Linux.
For the Windows and Mac, disable all the features by default.
For the Linux, if you have the realtime support in OS, you can enable the realtime feature.
To enable the fpga feature, make sure you have the expected hardware environment to load the FPGA bitfile (see the ts_mtm2_cell).
Follow here to install the Rust in cRIO.
To avoid the stack overflow, do the following in the cRIO:
ulimit -s unlimitedTo run the application in the simulation mode by cargo, do:
cargo run --bin run_m2 -- -sIf you are using the cRIO simulator, you can do the following instead:
cargo run --features realtime --bin run_m2 -- -sYou can interrupt the running application by ctrl + c.
To run the application in the hardware mode with FPGA by cargo, do:
cargo run --features fpga --bin run_m2Since the FPGA bitfile comes from ts_mtm2_cell, you need to make sure your target model is the same.
To get more information, do:
cargo run --bin run_m2 -- -hTo run the test FPGA code in the cRIO, do:
cargo run --features fpga --bin test_fpgaThe system should look for the /usr/lib/x86_64-linux-gnu/libNiFpga.so by itself at compile time.
See the build.rs.
The followings are the executables:
- main: M2 controller.
- test_fpga: Test script of FPGA for the M2 cRIO simulator in the electronic lab. This cRIO is the same model of the current cRIO of M2. It has the same NI modules as well.
Do the following to build the M2 controller executable:
cargo build --release --features fpga,realtimeFor the cRIO simulator, do the following instead (to enable the realtime feature is optional):
cargo build --release --features realtimeThis will generate an optimized executable in the target/release/ directory, which is suitable for distribution.
You should put the FPGA files in the fpga/ directory.
They are generated from the bifile of ts_mtm2_cell.
See FPGA Interface C API User Manual for more details.
Although the raw dynamic library is used and you do not really compile the NI FPGA C code, it is good to have the generated header file (NiFpga_portSerialMasterSlave.h) to get the register offsets.
Otherwise, you need to read the NI FPGA bitfile (an xml file) to get the required offsets.
Since the safety module needs the NI FPGA hybrid mode and the NI raw dynamic library only allows to load the bitfile of pure FPGA mode, we need to use the LabVIEW application to load the bitfile first to let this Rust-based application to be able to open the session of FPGA to control the hardware as a workaround at the moment. Hopefully the NI can support this in the future.
The details can follow deployment.
See the config/ directory for the configuration files:
- cell/actuator directory has the actuator configuration files.
- lut/ directory has the look-up tables of gravity and temperature.
- parameters_app.yaml is the configuration of application.
- parameters_control.yaml is the configuration of control loop.
- parameters_power.yaml is the configuration of power system.
- cell_geom.yaml is the cell geometry.
- cell_actuator_mapping.yaml is the mapping between the cell and actuators.
- home_position.yaml is the home position of mirror.
- disp_ims.yaml has the information of displacement sensors used in the independent measurement system (IMS).
- stiff_matrix_m2.yaml is the stiffness matrix of M2 mirror.
- stiff_matrix_surrogate.yaml is the stiffness matrix of surrogate.
- logspecification.toml assigns the log level.
Some useful scripts are in script/ directory.
m2: Initialization file in the Linux system. Note the run commands between the cRIO simulator and the real hardware are different. You need to do the related modification in the script.
The logging files contain the mirror position are in the log/ directory.
You can change the log level in the runtime by modifying the logspecification.toml.
The logging files are rotated, and the related parameters are in the parameters_app.yaml.
You can adjust the log level of each module individually.
To format the code, do:
.githooks/pre-commitThe docker file is here that contains the dependencies to generate the test and coverage reports to support the CI integration.
Each module and function have the related unit tests. Since the CI test is needed, you can use the cargo-nextest instead of the built-in test framework. Do the following to run all tests:
cargo nextest runTo test a single module, do:
cargo nextest run --lib $module_nameTo generate the junit.xml (ouput path is target/nextest/ci/junit.xml), do:
cargo nextest run --profile ciTo run the FPGA related test in cRIO, add the --features fpga flag when running the test.
For example, you can run the tests in the cRIO with:
cargo test fpga_hardware --features fpga -- --test-threads=1Note we need to use the flag --test-threads=1 here to make sure the system to run the test one by one.
Otherwise, you might get the error code: -52010:
A required resource was not properly initialized. This could occur if NiFpga_Initialize was not called or a required NiFpga_IrqContext was not reserved.
See here for the design of software.
The UML diagrams are used to detail the system design for each subsystem in the doc/ directory.
The GitHub supports the Mermaid natively.
You can use the online editor to edit them.
For the actuator ILC, if you do not issue the broadcast step() command first, the received status/force frame data is just some garbage data.
The status and force will be 0 and the encoder value is some random huge value (out of available encoder range).
For the monitor ILC, you might get the inf value when just starting up the ILCs.
We always have this for the temperature ILCs.
Sometime, the displacement ILC gives the inf value as well.
The ILC communication protocol is defined in:
- LSST-ILC Firmware: MODBUS Protocol Interface Control Document for M2 Support System
- LTS-346, ILC Communications Protocol For M2 Support System.
The data acquisition process is designed to support the realtime thread because:
- It needs to send a 10 Hz signal to the safety module reliably when the mirror control system is under the closed-loop control. If the safety module does not receive this signal, it will trigger the global interlock system (GIS) signal to stop the telescope motion.
- It needs to send the current power status (voltage and current) to the power system process reliably to check the health of the power system, especially when powering on/off the system.
Notes:
- The low-level PID controller is in the ILC.
The control system only sends the
step()command to the ILC. Therefore, in the theory, the data acquisition process does not need to be realtime for the hardware control with the ILC. - The control loop process will be woken up as soon as there is the new telemetry from the data acquisition process. Therefore, although the requirement document specifies the bandwidth of control loop to be 20 Hz, we do not need to make the control loop process to be realtime thread since the data acquisition process is 20 Hz as well. This can save the system resource significantly.
See here for the version history.