Add a New Hardware Device (Advanced)

navigate includes several standard hardware device types. These include:

  • Cameras

  • Data Acquisition Cards

  • Filter Wheels

  • Galvo Scanners

  • Lasers

  • Deformable Mirrors

  • Remote Focusing Systems

  • Shutters

  • Stages

  • Zoom Devices

To add a new piece of hardware to one of these device types requires knowledge about the software’s device abstraction layer. Here’s a detailed guide to help you integrate new CustomStage device into navigate. The same principles work for other device types.

Note

A strong knowledge of Python and object-oriented programming is required to integrate new hardware devices into navigate.


What is the Device Abstraction Layer?

To ensure compatibility and extendability, navigate utilizes a device abstraction layer, which allows the same commands to be used across different hardware devices. For example, all stages in navigate are programmed to include the stop() command, which can be used to stop the stage’s movement. When someone hits the Stop Stage button on the GUI, this action is relayed from the Controller to the Model and ultimately the CustomStage, which communicates with the hardware in a device-specific format to stop the stage’s movement.


Device Integration Approaches

There are two primary approaches to integrating new hardware into navigate:

  • Plugin:

    If you want to continue to work with an up-to-date version of navigate, consider integrating your new hardware device as a plugin. This allows you to pull updates from the main repository without losing your custom hardware integration. It also allows you to integrate non-standard device types. Learn more about the plugin architecture here, and how to write a custom plugin here.

  • Fork:

    Alternatively, you can fork the navigate repository on GitHub and modify it directly. This is useful for custom, in-house developments. In select circumstances, you can contribute your changes back to the main repository through a pull request. Please contact the navigate development team for guidance on this approach.


Device Class Creation

  • New hardware devices must have a corresponding device class in navigate. To ensure consistency and reduce redundancy, each device must inherit the appropriate abstract base class. For instance, a CustomStage device would inherit from StageBase.

  • Classes should follow CamelCase naming conventions and reflect the device they control (e.g., NewportStage for a stage from the manufacturer Newport).

  • Place the new device class within the appropriate device directory, src/navigate/model/devices/.

  • Place related API or hardware documentation within the appropriate manufacturer directory, typically under src/navigate/model/devices/APIs/.


Establish Device Communication

  • Each device requires a unique method to initialize a connection, which may involve APIs, serial communication, or other protocols. This method should be separate from the device class and is typically located at the beginning of the device file.

  • For example, a function named build_custom_stage_connection() would handle the connection setup for CustomStage class.

  • By separating the connection setup from the device class, you can easily interact with the hardware device outside of the larger navigate ecosystem, which can be useful for debugging and testing (e.g., within a Jupyter notebook).


Device Class Constructor

  • The constructor for the device class (__init__) should accept parameters for the microscope_name, device_connection, configuration_file, and an optional device_ID (useful when multiple instances of the same device are used).

  • The constructor should load and enforce device settings from the configuration_file. For a new stage, this could be defining the axes mapping between navigate and the device, {x:’X’, y:’Y’, z:’Z’}.

  • Ensure the device class uses the connection established by your build_custom_stage_connection method.


Device Class Methods

  • Implement any necessary device-specific methods within your device class.

  • Essential methods are inherited from the base class (e.g., StageBase for the CustomStage), but you can override them or add new methods as needed for specialized functionality.


Startup and Configuration

  • Utilize or modify methods within src/navigate/model/device_startup_functions to configure and start your device upon system initialization.

  • These functions should handle configuration parsing and the device communication setup.

  • Implement a retry mechanism, such as auto_redial, to handle communication issues robustly, attempting multiple times before failing.


Integration with Microscope Object Configurations

  • Each microscope configuration in navigate that uses the new device should receive a reference to the established communication object.

  • This setup is defined in the configuration.yaml and handled within the device_startup_functions, ensuring each configuration has access to the necessary hardware.


Testing and Validation

  • Thoroughly test the new hardware integration to ensure it functions correctly within navigate, across all intended use cases and configurations.

  • The naming convention for test files is: test_ + module name.

  • Device test files are located in `testmodeldevices`

  • Device testing utilizes the pytest package.

By following these steps, you can effectively integrate new hardware into the navigate platform, enhancing its functionality and ensuring it meets specific experimental needs.