Skip to content

FEAT: Perceive EM class #6259

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 121 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
d1e173f
First perceive em try
Samuelopez-ansys Jun 6, 2025
7e5b96e
Add material manager
Samuelopez-ansys Jun 10, 2025
da5b6a3
Add IT Material
Samuelopez-ansys Jun 10, 2025
cefbbcf
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 10, 2025
9c4e254
Add Material test
Samuelopez-ansys Jun 10, 2025
1b21bfa
Load mesh
Samuelopez-ansys Jun 11, 2025
1023644
Add bird
Samuelopez-ansys Jun 12, 2025
4dde163
Add get item
Samuelopez-ansys Jun 13, 2025
e34a161
Revert _app
Samuelopez-ansys Jun 13, 2025
8dca5ca
Revert _app
Samuelopez-ansys Jun 13, 2025
ed4047b
Revert _app
Samuelopez-ansys Jun 13, 2025
7fccff9
Revert _app
Samuelopez-ansys Jun 13, 2025
28d784f
Revert _app
Samuelopez-ansys Jun 13, 2025
f8ba921
Revert _app
Samuelopez-ansys Jun 13, 2025
407b362
Revert _app
Samuelopez-ansys Jun 13, 2025
fddd75b
Revert _app
Samuelopez-ansys Jun 13, 2025
e209a30
Revert _app
Samuelopez-ansys Jun 13, 2025
e11f7d8
Revert _app
Samuelopez-ansys Jun 13, 2025
ab06e4a
Revert _app
Samuelopez-ansys Jun 13, 2025
37ad17c
Revert _app
Samuelopez-ansys Jun 13, 2025
ef816c4
Revert _app
Samuelopez-ansys Jun 13, 2025
67d3402
Revert _app
Samuelopez-ansys Jun 13, 2025
03f3ecc
Revert _app
Samuelopez-ansys Jun 13, 2025
e6829df
Revert _app
Samuelopez-ansys Jun 13, 2025
234ca65
Revert _app
Samuelopez-ansys Jun 13, 2025
65c83d2
Revert _app
Samuelopez-ansys Jun 13, 2025
d8957a1
Revert _app
Samuelopez-ansys Jun 13, 2025
43246aa
Revert _app
Samuelopez-ansys Jun 13, 2025
0a60b1a
Revert _app
Samuelopez-ansys Jun 13, 2025
544e412
Revert _app
Samuelopez-ansys Jun 13, 2025
7c7f52f
chore: adding changelog file 6259.added.md [dependabot-skip]
pyansys-ci-bot Jun 13, 2025
1ef55a7
Fix bird
Samuelopez-ansys Jun 13, 2025
7750192
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 13, 2025
2370490
Update bird
Samuelopez-ansys Jun 13, 2025
0acab96
Add FRTM post processing
Samuelopez-ansys Jun 13, 2025
9fa705e
Add docstring
Samuelopez-ansys Jun 13, 2025
c6a2ad8
API call transparent
Samuelopez-ansys Jun 14, 2025
6d84ab8
API call transparent
Samuelopez-ansys Jun 14, 2025
ad1f67f
API call transparent
Samuelopez-ansys Jun 14, 2025
57b4597
Antenna device
Samuelopez-ansys Jun 15, 2025
c826736
Antenna device
Samuelopez-ansys Jun 15, 2025
1592e3d
Is receiver
Samuelopez-ansys Jun 15, 2025
64ca3d7
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 15, 2025
7b33e60
Is receiver
Samuelopez-ansys Jun 15, 2025
2313d27
Waveform
Samuelopez-ansys Jun 16, 2025
99e7f8b
Add antenna
Samuelopez-ansys Jun 16, 2025
bfadf81
Add antenna
Samuelopez-ansys Jun 16, 2025
e729b94
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 16, 2025
bf72e50
Add antenna
Samuelopez-ansys Jun 17, 2025
87eb78a
Add simulation
Samuelopez-ansys Jun 19, 2025
8aa29f5
Add simulation
Samuelopez-ansys Jun 19, 2025
68947b5
Add exception message
Samuelopez-ansys Jun 19, 2025
6e1c836
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 19, 2025
26cba63
Fix dataclass
Samuelopez-ansys Jun 19, 2025
8c7e105
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 23, 2025
ed0711a
Get settings
Samuelopez-ansys Jun 23, 2025
d3da102
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 23, 2025
29e46a2
API interface
Samuelopez-ansys Jun 23, 2025
cf5c503
Fix materials codacy
Samuelopez-ansys Jun 23, 2025
806d039
Fix aedt_version codacy
Samuelopez-ansys Jun 23, 2025
2271067
Scene root
Samuelopez-ansys Jun 23, 2025
0e48054
Antenna platform
Samuelopez-ansys Jun 23, 2025
16cf252
Antenna
Samuelopez-ansys Jun 23, 2025
394b355
Mode
Samuelopez-ansys Jun 23, 2025
c4d257f
Mode
Samuelopez-ansys Jun 23, 2025
7358975
Simulation
Samuelopez-ansys Jun 23, 2025
59dbdcd
Simulation
Samuelopez-ansys Jun 23, 2025
791c70a
Waveform codacy
Samuelopez-ansys Jun 23, 2025
c454b39
Fix codacy
Samuelopez-ansys Jun 23, 2025
e50535e
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 23, 2025
191873c
Waveform
Samuelopez-ansys Jun 24, 2025
898377f
Fix codacy
Samuelopez-ansys Jun 24, 2025
d0c9304
Fix codacy
Samuelopez-ansys Jun 24, 2025
1c6607e
Fix filter
Samuelopez-ansys Jun 24, 2025
bb59bcc
Add first doc
Samuelopez-ansys Jun 24, 2025
9c345ca
Antenna tests
Samuelopez-ansys Jun 24, 2025
bd2e136
Mode tests
Samuelopez-ansys Jun 24, 2025
33ef312
Add perceive em test
Samuelopez-ansys Jun 24, 2025
9b7288b
Fix docstring
Samuelopez-ansys Jun 24, 2025
37e5239
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 24, 2025
bd136f1
Add Perceive EM
Samuelopez-ansys Jun 24, 2025
67eb83d
Fix Codacy
Samuelopez-ansys Jun 24, 2025
2173e82
Perceive EM doc
Samuelopez-ansys Jun 24, 2025
46d4040
Antenna device tests
Samuelopez-ansys Jun 24, 2025
c486f13
Waveform tests
Samuelopez-ansys Jun 24, 2025
990b2a3
Fix picture
Samuelopez-ansys Jun 24, 2025
f984fdd
Move advanced actor
Samuelopez-ansys Jun 25, 2025
190f6ef
Advanced actor test
Samuelopez-ansys Jun 25, 2025
68bbe5e
Actor test
Samuelopez-ansys Jun 25, 2025
4d1aae8
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 25, 2025
257b461
Include pytest timeout
Samuelopez-ansys Jun 25, 2025
93cdea0
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 25, 2025
29841f8
Include pytest timeout
Samuelopez-ansys Jun 25, 2025
83687c3
Add perceive_em
Samuelopez-ansys Jun 25, 2025
5f4e2d3
Add coordinate system
Samuelopez-ansys Jun 25, 2025
eb1b5d3
Antenna platform test
Samuelopez-ansys Jun 25, 2025
00caa6f
Antenna platform test
Samuelopez-ansys Jun 25, 2025
de225e9
Load mesh test
Samuelopez-ansys Jun 25, 2025
d1f316a
Fix codacy
Samuelopez-ansys Jun 25, 2025
931c5d6
Add ffd and stl to manifest
Samuelopez-ansys Jun 25, 2025
723277a
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 25, 2025
f1c00cf
CHORE: Auto fixes from pre-commit hooks
pre-commit-ci[bot] Jun 25, 2025
e4ed191
Add doc
Samuelopez-ansys Jun 25, 2025
5026eb1
Merge remote-tracking branch 'origin/feat/perceive_em' into feat/perc…
Samuelopez-ansys Jun 25, 2025
aefeb96
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 26, 2025
b74c2f5
Add cicd deps
Samuelopez-ansys Jun 26, 2025
b49f99f
Fix doc
Samuelopez-ansys Jun 26, 2025
34ff218
Fix doc
Samuelopez-ansys Jun 26, 2025
876ae62
Add documentation
Samuelopez-ansys Jun 26, 2025
c942db5
Add documentation
Samuelopez-ansys Jun 26, 2025
4a8e365
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 26, 2025
24fdcb5
Add documentation
Samuelopez-ansys Jun 26, 2025
fb74c02
Fix vale
Samuelopez-ansys Jun 26, 2025
c24b779
Add pyvista
Samuelopez-ansys Jun 26, 2025
30d4b65
Add pyvista
Samuelopez-ansys Jun 27, 2025
466f0dd
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 27, 2025
bc24244
Test scene visualization
Samuelopez-ansys Jun 27, 2025
68fa738
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jun 27, 2025
c1371d5
Merge branch 'main' into feat/perceive_em
Samuelopez-ansys Jul 21, 2025
73dc980
Check tests
Samuelopez-ansys Jul 21, 2025
13d5b6b
Check tests
Samuelopez-ansys Jul 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
791 changes: 13 additions & 778 deletions .github/workflows/ci_cd.yml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1 +1 @@
global-include ansys.aedt.core *.txt *.md *.toml *.json *.png *.xml *.areg *.joblib *.acf *.m *.ipynb *.py_build
global-include ansys.aedt.core *.txt *.md *.toml *.json *.png *.xml *.areg *.joblib *.acf *.m *.ipynb *.py_build *.stl *.ffd
1 change: 1 addition & 0 deletions doc/changelog.d/6259.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Perceive em class
4 changes: 2 additions & 2 deletions doc/source/API/FilterSolutions.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Filter design
====================
=============
This section describes the classes used for creating and modifying parameters in the ``filtersolutions`` module.
The module provides tools for designing and customizing filter configurations.

Expand All @@ -9,7 +9,7 @@ Each class implements methods specific to its design approach while leveraging c


Lumped design
~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~
The ``LumpedDesign`` module includes all the necessary classes for creating and modifying parameters used in lumped filter designs.
Lumped filters use discrete components such as capacitors, inductors, and resistors.

Expand Down
292 changes: 292 additions & 0 deletions doc/source/API/PerceiveEM.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
Perceive EM
===========
Perceive EM is a highly performant, physical optics (PO)-based shooting and bouncing rays (SBR)
technology deployed through a lightweight API that seamlessly integrates into any digital twin platform.

.. note::
Requires Perceive EM 2025 R1 or later.


The ``PerceiveEM`` class is the main interface to the **Ansys Perceive EM API**, designed to provide simulation control,
scene management, and material definition for radar sensor simulation scenarios. It acts as a Python wrapper
within PyAEDT to seamlessly interact with the underlying native API.

.. currentmodule:: ansys.aedt.core.perceive_em.core.api_interface

.. autosummary::
:toctree: _autosummary
:nosignatures:

PerceiveEM


Initialization
--------------

The constructor allows specifying a Perceive EM version. If not provided, it attempts to auto-detect
the latest supported version installed on the system.


.. code-block:: python

from ansys.aedt.core.perceive_em.core.api_interface import PerceiveEM

perceive_em = PerceiveEM()


Simulation workflow
-------------------

Perceive EM has the simulation workflow described in the following picture:


.. image:: ../_static/perceive_em_workflow.png
:width: 800
:alt: Perceive EM workflow
:target: https://www.ansys.com/products/electronics/ansys-perceive-em


The Perceive EM API includes classes for the different simulation steps:


.. grid:: 2

.. grid-item-card:: Scene
:link: perceive_em/scene
:link-type: doc
:margin: 2 2 0 0

Manage actors and antenna platforms

.. grid-item-card:: Material
:link: perceive_em/material
:link-type: doc
:margin: 2 2 0 0

Manage materials

.. grid-item-card:: Simulation
:link: perceive_em/simulation
:link-type: doc
:margin: 2 2 0 0

Manage simulation settings


Example
-------

This example builds a complete scene and launch the simulation.


.. code-block:: python

from pathlib import Path
import numpy as np
import matplotlib.pyplot as plt

from ansys.aedt.core.generic.settings import settings
from ansys.aedt.core.perceive_em.core.api_interface import PerceiveEM
from ansys.aedt.core.perceive_em.scene.antenna_platform import AntennaPlatform
from ansys.aedt.core.perceive_em.modules.antenna_device import AntennaDevice
from ansys.aedt.core.perceive_em.modules.antenna import Antenna
from ansys.aedt.core.perceive_em.modules.material import MaterialManager
from ansys.aedt.core.perceive_em import MISC_PATH
from ansys.aedt.core.perceive_em.visualization.scene_visualization import SceneVisualization

from ansys.aedt.core.perceive_em.modules.waveform import RangeDopplerWaveform
from ansys.aedt.core.perceive_em.modules.antenna import Transceiver

"""User inputs"""

"""Waveform"""
center_freq = 77e9
num_freqs = 512
bandwidth = 300e6
cpi_duration = 10e-3
num_pulse_CPI = 101

waveform = RangeDopplerWaveform()
waveform.center_frequency = center_freq
waveform.bandwidth = bandwidth
waveform.pulse_cpi = num_pulse_CPI
waveform.frequency_samples = num_freqs
waveform.cpi_duration = cpi_duration

"""Scene definition"""
frames_per_second = 30
dt = 1 / frames_per_second
T = 10
frame_number = int(T / dt)

update_camera_view = False
actor_attachment = None
# side, top, front , scene_top, first_person, third_person
camera_orientation = "scene_top"
distance_factor = 3.0
height_factor = 2.2

"""Transceivers"""
tx = Transceiver()
tx.name = 'antenna_tx'
tx.antenna_type = "farfield"
tx.input_data = MISC_PATH / "antenna_device_library" / "dipole.ffd"
tx.operation_mode = "Tx"

rx = Transceiver()
rx.name = 'antenna_rx'
rx.antenna_type = "farfield"
rx.input_data = MISC_PATH / "antenna_device_library" / "dipole.ffd"
rx.operation_mode = "Rx"

"""Simulation options"""
# Set to -1 if no GO blockage, set to 0 or higher for GO blockage
go_blockage = 1
max_num_refl = 5
max_num_trans = 1
ray_spacing = 0.55

# Bird trajectory
circle_radius = 3
orbit_center = np.array([5, 0, 1])

########################################################################################################################
"""PyAEDT Perceive EM API"""
########################################################################################################################

"""Initialize scene"""
perceive_em = PerceiveEM()

"""Add bird to scene"""
actor_bird = perceive_em.scene.add_bird(name="bird",
input_file=MISC_PATH / "actor_library" / "bird" / "bird.json")

"""Add city to scene"""
material_manager = MaterialManager(perceive_em)
available_materials = material_manager.available_materials
# If material is not available you can add a new one using add_material method
actor_city = perceive_em.scene.add_actor(name="city")
actor_city.add_part(input_file=MISC_PATH / "actor_library" / "city.stl",
name=None,
material="asphalt",
color="white",
transparency=0.8)

"""Add antenna single Tx and Rx"""
antenna_platform = perceive_em.scene.add_single_tx_rx(tx=tx, rx=rx, waveform=waveform)

"""Bird scene"""
interp_func_pos_bird, interp_func_rot_bird = actor_bird.circle_trajectory(
duration=T,
n_frames=frame_number,
circle_radius=circle_radius,
orbit_center=orbit_center,
rotation_start_deg=90,
rotation_end_deg=450)

# Visualization object

# Scale farfield to improve visibility
antenna_devices = antenna_platform.antenna_devices[antenna_platform.antenna_device_names[0]]
modes = antenna_devices.modes[antenna_devices.mode_names[0]]
antenna_rx = modes.antennas_rx["antenna_rx"].scale_mesh = [0.1, 0.1, 0.1]
antenna_tx = modes.antennas_tx["antenna_tx"].scale_mesh = [0.1, 0.1, 0.1]

actors = perceive_em.scene.actors
actors.update(perceive_em.scene.antenna_platforms)

modeler = SceneVisualization(actors, size=(1920, 1088))
modeler.camera_orientation = camera_orientation
modeler.camera_attachment = actor_attachment
modeler.height_factor = height_factor
modeler.distance_factor = distance_factor

# Simulation setup

perceive_em.simulation.ray_spacing = ray_spacing
perceive_em.simulation.max_reflections = max_num_refl
perceive_em.simulation.max_transmissions = max_num_trans
perceive_em.simulation.go_blockage = go_blockage
perceive_em.simulation.field_of_view = 180

perceive_em.simulation.auto_configure_simulation()

perceive_em.simulation.response_type = perceive_em.simulation.response_types["range_doppler"]
perceive_em.simulation.mode = antenna_platform.antenna_devices[antenna_platform.antenna_device_names[0]].active_mode

perceive_em.simulation.validate()


plt.ion()

fig, ax = plt.subplots()
self = type('', (), {})()
self.ax = ax
self.fig = fig

imData = np.random.rand(100, 100)
self.mpl_ax_handle = ax.imshow(imData, cmap='viridis')

plot_limits = None

update_time = 0
for frame in range(frame_number):
time = frame * dt

# Update actor position
for actor_name, actor in perceive_em.scene.actors.items():
if time > 10:
update_time = np.mod(update_time, 10)
else:
update_time = time
if hasattr(actor, "actor_type") and actor.actor_type == "bird":
actor.coordinate_system.auto_update = False
actor.coordinate_system.position = interp_func_pos_bird(update_time)
actor.coordinate_system.rotation = interp_func_rot_bird(update_time)
actor.coordinate_system.auto_update = True
actor.update(time=update_time)

for antenna_platform_name, antenna_platform in perceive_em.scene.antenna_platforms.items():
if time > 10:
update_time = np.mod(update_time, 10)
else:
update_time = time
antenna_platform.update(time=update_time)

modeler.update_frame(update_camera_view=update_camera_view)

perceive_em.simulation.analyze()
response = perceive_em.simulation.get_solution_data()

imData = np.rot90(20 * np.log10(np.fmax(np.abs(response[0][0]), 1.e-30)))

if isinstance(imData, list):
imData = np.array(imData)

if imData.ndim == 1:
if not hasattr(self, 'mpl_ax_handle') or not isinstance(self.mpl_ax_handle, plt.Line2D):
ax.clear()
self.mpl_ax_handle, = ax.plot(imData)
else:
self.mpl_ax_handle.set_ydata(imData)
self.ax.set_ylim(np.min(imData), np.max(imData))
else:
self.mpl_ax_handle.set_data(imData)
if plot_limits is not None:
self.mpl_ax_handle.set_clim(vmin=plot_limits[0], vmax=plot_limits[1])
else:
self.mpl_ax_handle.set_clim(vmin=np.min(imData), vmax=np.max(imData))

self.fig.canvas.draw()
self.fig.canvas.flush_events()
plt.pause(0.001)

modeler.close()

.. toctree::
:hidden:
:maxdepth: 2

perceive_em/scene
perceive_em/material
perceive_em/simulation
2 changes: 2 additions & 0 deletions doc/source/API/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ PyAEDT app to get access to all modules and methods. Available apps are:
- Circuit
- `TwinBuilder <https://www.ansys.com/products/digital-twin/ansys-twin-builder>`_
- `FilterSolutions <https://www.ansys.com/products/electronics/ansys-nuhertz-filtersolutions>`_
- `PerceiveEM <https://www.ansys.com/products/electronics/ansys-perceive-em>`_


All other classes and methods are inherited into the app class.
Expand Down Expand Up @@ -99,4 +100,5 @@ Example with ``Desktop`` class implicit initialization:
SetupTemplates
CableModeling
FilterSolutions
PerceiveEM
generic
14 changes: 14 additions & 0 deletions doc/source/API/perceive_em/material.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Material
========

Manages material definitions for a radar simulation scenario.


.. currentmodule:: ansys.aedt.core.perceive_em.modules.material

.. autosummary::
:toctree: _autosummary
:nosignatures:

MaterialManager
calculate_itu_properties
Loading
Loading