Skip to content

lsst-ts/ts_mtm2_controller

Repository files navigation

M2 Controller

This is the M2 control system.

Features

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.

Development Environment

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).

Install the Rust in cRIO and Run the Application

Follow here to install the Rust in cRIO.

To avoid the stack overflow, do the following in the cRIO:

ulimit -s unlimited

To run the application in the simulation mode by cargo, do:

cargo run --bin run_m2 -- -s

If you are using the cRIO simulator, you can do the following instead:

cargo run --features realtime --bin run_m2 -- -s

You 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_m2

Since 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 -- -h

To run the test FPGA code in the cRIO, do:

cargo run --features fpga --bin test_fpga

The system should look for the /usr/lib/x86_64-linux-gnu/libNiFpga.so by itself at compile time. See the build.rs.

Executables

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.

Build the Executable

Do the following to build the M2 controller executable:

cargo build --release --features fpga,realtime

For the cRIO simulator, do the following instead (to enable the realtime feature is optional):

cargo build --release --features realtime

This will generate an optimized executable in the target/release/ directory, which is suitable for distribution.

FPGA Files

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.

Deployment

The details can follow deployment.

Configuration Files

See the config/ directory for the configuration files:

Script

Some useful scripts are in script/ directory.

  1. 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.

Log Data

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.

Code Format

To format the code, do:

.githooks/pre-commit

Docker File

The docker file is here that contains the dependencies to generate the test and coverage reports to support the CI integration.

Unit Test

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 run

To test a single module, do:

cargo nextest run --lib $module_name

To generate the junit.xml (ouput path is target/nextest/ci/junit.xml), do:

cargo nextest run --profile ci

To 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=1

Note 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.

Software Architecture

See here for the design of software.

UML Diagrams

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.

Tricky Parts of the Code Tuning with the Inner-Loop Controller (ILC)

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.

ILC Communication Protocol

The ILC communication protocol is defined in:

  1. LSST-ILC Firmware: MODBUS Protocol Interface Control Document for M2 Support System
  2. LTS-346, ILC Communications Protocol For M2 Support System.

Realtime Thread Support

The data acquisition process is designed to support the realtime thread because:

  1. 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.
  2. 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:

  1. 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.
  2. 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.

Version History

See here for the version history.

About

M2 controller in Rust

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors