Skip to content

Cosys-Lab/sonotraceuepy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sonotraceuepy

Python module serving as an interface client to interact with the Unreal Engine implementation of SonoTraceUE.

Installation

You can install the Python client from pip with pip install sonotraceuepy

From source clone this repository and run:

pip install -e .
# or, for the optional interactive 3D PyVista world-scatter plot:
pip install -e ".[pyvista]"

Dependencies

  • Unreal Engine with SonoTraceUE Plugin v3.1.0 or higher.
  • Python 3.12 or higher
    • numpy
    • scipy
    • matplotlib

Coordinate System Convention

sonotraceuepy coordinate system:

  • Right-handed
  • X: Forward, Y: Right, Z: Up
  • Units: meters

Unreal Engine coordinate system:

  • Left-handed, Z-up
  • Units: centimeters

Conversions happen transparently via transforms.unreal_position_to_local/local_position_to_unreal (positions) and transforms.unreal_pose_to_matrix/matrix_to_unreal_pose.

General Usage

import sonotraceuepy as stp

stp.configure_logging("INFO")

interface = stp.Interface("localhost", 9098)
settings = interface.receive_settings()
settings.prepare_ir_and_signal_generation(
    number_of_samples_ir_filter=256,
    enable_pattern_sum=True,
    ir_filter_gauss_alpha=5,
    number_of_ir_samples=18000,
    approximate_ir_cut_db=-90,
    enable_approximate_ir=False,
    use_base_kernels=True,
)

while True:
    if not interface.trigger_measurement():
        break
    data, data_type = interface.receive_data()
    if data_type != 1:  # not a Measurement
        break

    measurement = data
    measurement.impulse_responses = stp.synthesize_ir_from_points(
        measurement.reflected_points,
        sample_rate=settings.sample_rate,
        number_of_samples_ir_filter=settings.number_of_samples_ir_filter,
        frequencies=settings.frequencies,
        ir_filter_gauss_alpha=settings.ir_filter_gauss_alpha,
        number_of_ir_samples=settings.number_of_ir_samples,
        number_of_emitters=measurement.number_of_emitters,
        number_of_receivers=measurement.number_of_receivers,
        approximate_ir_cut_db=settings.approximate_ir_cut_db,
        enable_approximate_ir=settings.enable_approximate_ir,
        speed_of_sound=settings.speed_of_sound,
    )
    measurement.receiver_signals = stp.generate_receiver_signals_from_ir(
        measurement.impulse_responses, settings.emitter_signals, measurement.emitter_signal_indexes
    )

    stp.plot_measurement(measurement, plot_ir=True, plot_signals=True)

See examples/example.py for a complete example.

API Reference

Interface

TCP server that Unreal's plugin connects to.

interface = stp.Interface(server_ip="localhost", server_port=9098)

Key methods: receive_settings(), trigger_measurement(override_emitter_signal_indexes=None), receive_data(), send_data_message(data_message), set_new_sensor_world_transform(matrix, teleport=False), set_new_sensor_relative_transform(matrix), set_new_sensor_owner_world_transform(matrix, teleport=False), set_new_emitter_positions(indexes, positions_m, relative_transform, re_apply_offset), set_new_receiver_positions(...), set_current_emitter_signal_indexes(indexes), get_current_emitter_signal_indexes().

Settings

One-time simulation configuration (emitter/receiver positions, ray tracing parameters, object BRDF/material settings, frequencies, emitter signal waveforms). Call settings.prepare_ir_and_signal_generation(...) once before synthesizing impulse responses.

Measurement

Everything from one triggered acoustic measurement: sensor_pose/owner_pose/emitter_poses/ receiver_poses (4x4 matrices, emitter_poses/receiver_poses shaped (N, 4, 4)), reflected_points (a ReflectedPoints structure-of-arrays), direct_path_los, specular_sub_output/diffraction_sub_output/direct_path_sub_output (each a SubOutput, present only if the plugin's component-separated output is enabled).

ReflectedPoints

A structure-of-arrays (not a Python object per point, for speed): location, reflection_direction (N, 3); summed_strength, total_distance, distance_to_sensor, curvature_magnitude, object_type_index, ray_index, bounce_index, is_hit, is_last_hit, is_specular, is_diffraction, is_direct_path, label (N,); total_distances_from_emitters, emitter_directivities (N, E); strengths (N, E, R, F); total_distance_to_receivers (N, E, R).

Signal processing

  • synthesize_ir_from_points(reflected_points, sample_rate, number_of_samples_ir_filter, frequencies, ir_filter_gauss_alpha, number_of_ir_samples, number_of_emitters, number_of_receivers, approximate_ir_cut_db, enable_approximate_ir, speed_of_sound)(E, R, number_of_ir_samples) impulse responses.
  • generate_receiver_signals_from_ir(impulse_responses, emitter_signals, emitter_signal_indexes)(R, samples) receiver signals (convolves each emitter's IR with its assigned emitter signal).
  • generate_ir_base_kernels(sample_rate, frequencies, ir_filter_gauss_alpha, number_of_samples_ir_filter), fm_sweep(f_start, f_end, sample_rate, duration_ms, amplitude, window_percent), norm_lin, norm_log.

Plotting

  • plot_measurement(measurement, plot_sensor=True, plot_reflected_points=True, plot_direct_path_flag=False, plot_ir=False, plot_signals=False, db_cutoff=60.0, plot_limit_around_sensor=False) - convenience all-in-one entry point, returns a dict of the figures it created.
  • plot_world(measurement, ...) - Matplotlib 3D scatter of poses + reflected points colored by strength.
  • plot_world_interactive(measurement, ...) - the same, but an interactive/rotatable PyVista viewer (requires the optional pyvista extra).
  • plot_direct_path(measurement, ...), plot_sub_output(sub_output, title, db_cutoff), plot_impulse_responses(impulse_responses, sample_rate), plot_receiver_signal_spectrograms(receiver_signals, sample_rate).

DataMessage

Generic typed string/int/float channel for custom data exchange with the plugin (e.g. requesting a scene-capture image, as in examples/example.py).

message = stp.DataMessage(
    type=1,
    order=[stp.DataFieldType.FLOAT, stp.DataFieldType.STRING],
    strings=["hello"],
    integers=[],
    floats=[3.14],
)
interface.send_data_message(message)

License

This project is released under the CC-BY-NC-SA-4.0 license.

About

Python client implementation of the API of the SonoTraceUE Unreal Engline Plugin

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages