Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Implementing New Hardware Devices with Rattlesnake

11Implementing New Hardware Devices with Rattlesnake

Rattlesnake allows users to implement new hardware devices with minimal modifications to the controller. Within the GitHub repository, there is a source file components/abstract_hardware.py that defines abstract base classes HardwareAcquisition and HardwareOutput. All hardware devices used by Rattlesnake must implement acquisition and output classes that inherit from these abstract base classes and define functions that overwrite the abstract methods in these base classes.

The acquisition and output will generally be run on separate processes in Rattlesnake to ensure that output can be streamed to the device as acquired data is simultaneously read from the device. A flowchart of the operations performed by each hardware process is shown in Figure 11.1.

Flowchart of Hardware Operations. Note that each process will proceed at its own pace, so it is generally not possible to ensure that an Acquisition function is called before or after an Output function. The only place where order of operations is enforced is at startup, where the Output start function finishes before the Acquisition start function is called.

Figure 11.1:Flowchart of Hardware Operations. Note that each process will proceed at its own pace, so it is generally not possible to ensure that an Acquisition function is called before or after an Output function. The only place where order of operations is enforced is at startup, where the Output start function finishes before the Acquisition start function is called.

The hardware setup in Rattlesnake generally assumes that separate processes are required for acquisition and output. However, this may not be the case for all hardware devices. If a device can only run on a single process, users can utilize a multiprocessing queue to pass the output data from the output process to the acquisition process and perform all hardware processes there. See, for example, the hardware implementation in components/state_space_virtual_hardware.py for more details on this approach; the excitation signal is obtained by the write method and immediately passed to a queue to deliver to the acquisition process.

Users implementing new hardware devices are encouraged to look at existing hardware implementations in the Github Repository repository (components/nidaqmx_hardware_multitask.py, components/lanxi_hardware.py, components/data_physics_hardware.py, components/state_space_virtual_hardware.py, components/sdynpy_system_virtual_hardware.py, and components/exodus_modal_solution_hardware.py) to use as examples.

11.1Defining a HardwareAcquisition Class

The acquisition portion of the data acquisition hardware is defined using a class that inherits the abstract base class HardwareAcquisition in components/abstract_hardware.py. A class inheriting from HardwareAcquisition must implement the following functions.

11.1.1Defining a HardwareOuput Class

The acquisition portion of the data acquisition hardware is defined using a class that inherits the abstract base class HardwareOutput in components/abstract_hardware.py. A class inheriting from HardwareOutput must implement the following functions.

11.2Controller Modifications to Recognize New Hardware Devices

With the new hardware device implemented, the controller should be modified to find the new hardware device and allow the user to run it.

11.2.1Graphical user interface (GUI) Modifications

In order for the user to select the newly-implemented hardware device, the hardware must be added to the Hardware Selector drop-down menu on the Data Acquisition Setup tab of the controller. This requires editing the components/combined_environments_controller.ui file. Editing of *.ui files is most easily done through the Qt Designer software, but can also be done by editing the *.ui file directly, as it contains XML. The widget that needs to be modified is a QComboBox widget with the name hardware_selector. An additional item needs to be added to the widget corresponding to the hardware device.

If the hardware requires additional user parameters to be specified, then further modifications to the GUI might be required. Such modifications will require a thorough understanding of the Rattlesnake source code. These modifications will be highly specific to the hardware being implemented, and are therefore out of scope for this User’s Manual. Such modifications might include adding a dropdown to select a trigger channel to synchronize acquisition and output or adding integration parameters such as minimum or maximum timestep for a virtual hardware device that utilizes a nonlinear integrator.

11.2.2Modifications to the User interface (UI) Callback Functions

With the GUI modified to enable selecting the hardware interface, the user might need to modify the Hardware Selector callback function in order to ensure the proper options are visible to the user. These callbacks are defined in the components/user_interface.py file in the Ui class. The hardware_update function may need to be modified to handle hiding or showing specific widgets when the new hardware device is selected.

If the hardware interface requires additional user parameters to be specified, then further modifications to the code will be required. These modifications will be highly specific to the hardware being implemented, so this User’s Manual will only discuss where the changes will need to be made, but not necessarily what those changes need to be. If additional parameters are required, users may need to modify the DataAcquisitionParameters class found in components/utilities.py to add these additional parameters to the global parameter set. The user will also need to modify the code where the class is instantiated to include these new parameters, particularly in the initialize_data_acquisition function of the Ui class in components/user_interface.py.

11.2.3Modifications to the Acquisition and Output Processes

Finally, the initialize_data_acquisition functions in both the AcquisitionProcess class in components/acquisition.py and the OutputProcess class in components/output.py will need to be modified to correctly initialize the hardware. A new elif statement should be added to the main if statement inside that function to accommodate the new hardware device index that was added to the Hardware Selector dropdown menu. The *.py file that contains the hardware implementation should be imported and the respective Acquisition or Output class should be instantiated. It is at this point that any additional arguments to the classes’ __init__ functions are passed. The object instantiated from the class should be stored to the self.hardware property of the class.