This project contains a ROS2-based ultrasonic data acquisition and processing system for Evo hardware, with real-time visualization and parameter control.
The system consists of three main ROS2 nodes that work together:
- Publisher Node (
publisher.py) - Interfaces with Evo hardware to acquire ultrasonic A-scan data - Processor Node (
processor.py) - Processes raw A-scan data and displays real-time visualizations - Controller Node (
controller.py) - Provides a GUI for monitoring and controlling system parameters
┌─────────────────┐ Ascan Message ┌─────────────────┐
│ │ ──────────────────────> │ │
│ Publisher │ │ Processor │
│ (Hardware I/O) │ │ (Visualization) │
└─────────────────┘ └─────────────────┘
↑ ↑
│ │
│ ROS2 Parameters │
└───────────────────┬───────────────────────┘
│
┌────────────────┐
│ Controller │
│ (GUI) │
└────────────────┘
Purpose: Interfaces with Evo ultrasonic hardware to acquire A-scan waveform data from up to 2 channels.
The publisher does not include code on temperature gathering. You should implement your own temperature aquisition code, and there is a segment in the code where you can do this.
Parameters:
numAverages(int, 1-1000): Number of waveform averages used by the publisher for each published A-scan. The calibration flow temporarily modifies this value to improve SNR during collection.numChannels(int, 1-2): Number of active channels (1 or 2)numCycles(int, 1-3): Number of excitation cycles (read-only)numSamples(int): Number of samples to record (read-only)signalFrequency(int): EMAT signal frequency in Hz
Published Topics:
/ascan(interfaces/msg/Ascan): Contains active channels, encoded waveform data, and temperature
Purpose: Processes raw A-scan data and provides real-time visualization with automatic peak detection.
Key Features:
- Real-time matplotlib-based visualization for active channels
- Automatic subplot arrangement based on number of active channels
- Peak detection and thickness calculation
- Multiple processing modes (first peak, multi-echo, zero crossing)
- Temperature-corrected measurements
Parameters (per channel, ch1-ch2):
ch{N}_sampling_frequency(int): Sampling frequency in Hzch{N}_lowbound_time(int): Lower bound time in microsecondsch{N}_minimum_thickness(float): Minimum detectable thickness in mmch{N}_wave_velocity(float): Wave velocity in m/sch{N}_num_cycles(float): Number of cycles for processingch{N}_signal_frequency(int): Signal frequency in Hzch{N}_threshold_snr(float): SNR threshold in dBch{N}_noise_width(int): Noise calculation window widthch{N}_calibration_index(int): Calibration reference indexch{N}_firstPeak(bool): Enable first peak detection modech{N}_multiEcho(bool): Enable multi-echo modech{N}_zeroCrossing(bool): Enable zero crossing detectionch{N}_temperatureCorrected(bool): Enable temperature correctionch{N}_rectified(bool): Plot rectified/hilbert envelope instead of raw/full-wavech{N}_fullWave(bool): Plot full band-passed waveform
Subscribed Topics:
/ascan(interfaces/msg/Ascan): Receives waveform data from publisher
Purpose: Provides a PyQt5-based GUI for real-time parameter monitoring and control.
Key Features:
- Automatic discovery of ROS2 nodes and their parameters
- Tabbed interface with separate tabs for each active channel
- Parameter filtering based on configuration file
- Support for various parameter types (sliders, spinboxes, checkboxes)
- Real-time parameter updates with visual feedback
- Configurable display names and parameter bounds
Configuration (config.json):
multipleTabs: Enable/disable tabbed interfacewhitelist: Enable parameter whitelistinghideReadOnlyParameters: Hide read-only parameterswhitelistNodes: List of nodes to displaywhitelistParameters: Parameters to show per nodeparameterDisplayNames: Custom display names for parametersparameter_bounds: Min/max bounds for numeric parameters
The system uses 1-based channel numbering (1-2) for parameter names and user-facing labels.
- Channel parameters are named
ch1_*throughch2_*. - The publisher's
channelsOnReceiveparameter is an integer array indexed 0..N-1 (internal representation). The controller and processor map this to 1-based channel IDs for display and parameter naming. - The
Ascanmessage uses zero-based indices inactive_channels(0..), but the GUI/parameter names use 1-based channels.
int32[] active_channels # List of active channel indices (0-based) corresponding to which entries in ascan_data are present
string[] ascan_data # Base64-encoded waveform data for each active channel (float64 samples)
float32 temperature # Temperature reported by the publisher (if available)
int32 signal_frequency # EMAT pulser frequency
- ROS2 Humble or later (tested on Jazzy) (Desktop Variant is required for processor and controller)
- Evo ultrasonic system (for publisher)
- Under the project root folder, run
cd drivers
sudo ./sonobotics_runtime_<version&architecture>.deb
sudo ./sonobotics_waveforms_<version&architecture>.deb
tar -xvf pololu-jrk-g2-1.4.0-linux-x86.tar.xz
cd pololu-jrk-g2-1.4.0-linux-x86
sudo ./install.sh- Once drivers have been installed, run
colcon buildto build all the packages.
- Launch the publisher node (requires Evo hardware):
ros2 run ros_parameter_demo publisher- Launch the processor node for visualization:
ros2 run ros_parameter_demo processor- Launch the controller GUI:
ros2 run ros_parameter_demo controllerTo enable specific receive channels, modify the numChannels parameter in the publisher file.
Each channel can operate in different processing modes:
- First Peak: Detects the first significant peak in the waveform
- Multi-Echo: Processes multiple reflections
- Zero Crossing: Uses zero-crossing detection for improved accuracy
- Temperature Corrected: Applies temperature compensation to measurements
Note: First Peak and Multi-Echo modes are mutually exclusive.
If you set both in the controller, the processor falls back to which none of the four parameters are set.
EvoROS includes an interactive calibration workflow accessible from the Controller GUI.
Steps:
- Open the Controller GUI (
ros2 run ros_parameter_demo controller) and clickCalibrate. - Enter the known thickness of the calibration block (mm) and press
Start calibration. - The controller will temporarily set the publisher's
numAveragesto 40 to improve SNR, then collect a series of measurements (default collection target: 100 samples). - When collection completes the dialog shows a computed
Calibrated Speed of Soundvalue. - Press
Apply Speed of Soundto write the calibratedch{N}_wave_velocityvalue to any node that exposes per-channel*_wave_velocityparameters (for exampleascan_processor). The publisher'snumAveragesis restored afterwards.
Notes:
- The calibration dialog runs collection in a background subscription and attempts a best-effort restore of the original
numAveragesvalue. - If you have a custom publisher, ensure it exposes
numAveragesandchannelsOnReceiveparameters to integrate with the controller's calibration flow.
config.json: Controller GUI configuration- Channel parameters can be saved/loaded via ROS2 parameter services
- No visualization appears: Ensure at least one channel is enabled in
numChannels - Controller doesn't show parameters: Controller won't show anything until the publishing node is on. Check that nodes are running and
config.jsonwhitelist is correct. - Hardware errors: Verify Evo device is connected and permissions are set correctly.