commit f127614a581359c9620e7a3c78188f339ad2cf0e
parent bdae618a2bfe358310f5cc00b295da7610f68947
Author: Egor Achkasov <eaachkasov@edu.hse.ru>
Date: Wed, 2 Apr 2025 21:44:33 +0200
Fix bindings
Diffstat:
4 files changed, 112 insertions(+), 50 deletions(-)
diff --git a/compute_paths_pybind11.cpp b/compute_paths_pybind11.cpp
@@ -7,10 +7,13 @@
#ifdef _WIN32
extern "C" {
- #include "compute_paths.h"
+#endif
+ #include "inc/compute_paths.h"
+ #include "inc/scene.h"
+ #include "inc/vec3.h"
+ #include "inc/ray.h"
+#ifdef _WIN32
}
-#else
-#include "compute_paths.h"
#endif
namespace py = pybind11;
@@ -38,7 +41,7 @@ py::array_t<std::complex<float>> make_complex_array(
);
}
-class PathsInfoPython {
+class ChannelInfoPython {
public:
size_t num_paths;
py::array_t<float> directions_rx;
@@ -48,40 +51,52 @@ public:
py::array_t<float> tau;
py::array_t<float> freq_shift;
- PathsInfoPython(const PathsInfo& paths, size_t num_rx, size_t num_tx) {
- num_paths = paths.num_paths;
+ ChannelInfoPython(const ChannelInfo& chanInfo, size_t num_rx, size_t num_tx) {
+ num_paths = chanInfo.num_rays;
auto capsule_deleter = [](void* ptr) { delete[] static_cast<float*>(ptr); };
directions_rx = py::array_t<float>(
- std::vector<size_t>{num_rx, num_tx, (size_t)paths.num_paths, 3},
- paths.directions_rx,
- py::capsule(paths.directions_rx, capsule_deleter)
+ std::vector<size_t>{num_rx, num_tx, (size_t)chanInfo.num_rays, 3},
+ (float*)chanInfo.directions_rx,
+ py::capsule(chanInfo.directions_rx, capsule_deleter)
);
directions_tx = py::array_t<float>(
- std::vector<size_t>{num_rx, num_tx, (size_t)paths.num_paths, 3},
- paths.directions_tx,
- py::capsule(paths.directions_tx, capsule_deleter)
+ std::vector<size_t>{num_rx, num_tx, (size_t)chanInfo.num_rays, 3},
+ (float*)chanInfo.directions_tx,
+ py::capsule(chanInfo.directions_tx, capsule_deleter)
);
- a_te = make_complex_array(paths.a_te_re, paths.a_te_im, num_rx, num_tx, paths.num_paths);
- a_tm = make_complex_array(paths.a_tm_re, paths.a_tm_im, num_rx, num_tx, paths.num_paths);
+ a_te = make_complex_array(
+ chanInfo.a_te_re,
+ chanInfo.a_te_im,
+ num_rx,
+ num_tx,
+ chanInfo.num_rays
+ );
+ a_tm = make_complex_array(
+ chanInfo.a_tm_re,
+ chanInfo.a_tm_im,
+ num_rx,
+ num_tx,
+ chanInfo.num_rays
+ );
tau = py::array_t<float>(
- {num_rx, num_tx, (size_t)paths.num_paths},
- paths.tau,
- py::capsule(paths.tau, capsule_deleter)
+ {num_rx, num_tx, (size_t)chanInfo.num_rays},
+ chanInfo.tau,
+ py::capsule(chanInfo.tau, capsule_deleter)
);
freq_shift = py::array_t<float>(
- {num_rx, num_tx, (size_t)paths.num_paths},
- paths.freq_shift,
- py::capsule(paths.freq_shift, capsule_deleter)
+ {num_rx, num_tx, (size_t)chanInfo.num_rays},
+ chanInfo.freq_shift,
+ py::capsule(chanInfo.freq_shift, capsule_deleter)
);
}
};
-std::tuple<PathsInfoPython, PathsInfoPython>
+std::tuple<ChannelInfoPython, ChannelInfoPython>
compute_paths_wrapper(
const std::string &mesh_filepath,
py::array_t<float> rx_positions,
@@ -100,11 +115,14 @@ compute_paths_wrapper(
py::buffer_info rx_vel_info = rx_velocities.request();
py::buffer_info tx_vel_info = tx_velocities.request();
- // Output
- PathsInfo los = {
- .num_paths = 1,
- .directions_rx = new float[num_rx * num_tx * 3],
- .directions_tx = new float[num_rx * num_tx * 3],
+ // Load the scene
+ Scene scene = scene_load(mesh_filepath.c_str());
+
+ // Output channel information
+ ChannelInfo chanInfo_los = {
+ .num_rays = 1,
+ .directions_rx = new Vec3[num_rx * num_tx],
+ .directions_tx = new Vec3[num_rx * num_tx],
.a_te_re = new float[num_rx * num_tx],
.a_te_im = new float[num_rx * num_tx],
.a_tm_re = new float[num_rx * num_tx],
@@ -112,10 +130,10 @@ compute_paths_wrapper(
.tau = new float[num_rx * num_tx],
.freq_shift = new float[num_rx * num_tx]
};
- PathsInfo scatter = {
- .num_paths = (uint32_t)(num_bounces * num_paths),
- .directions_rx = new float[num_rx * num_tx * num_bounces * num_paths * 3],
- .directions_tx = new float[num_rx * num_tx * num_bounces * num_paths * 3],
+ ChannelInfo chanInfo_scat = {
+ .num_rays = (uint32_t)(num_bounces * num_paths),
+ .directions_rx = new Vec3[num_rx * num_tx * num_bounces * num_paths],
+ .directions_tx = new Vec3[num_rx * num_tx * num_bounces * num_paths],
.a_te_re = new float[num_rx * num_tx * num_bounces * num_paths],
.a_te_im = new float[num_rx * num_tx * num_bounces * num_paths],
.a_tm_re = new float[num_rx * num_tx * num_bounces * num_paths],
@@ -123,39 +141,59 @@ compute_paths_wrapper(
.tau = new float[num_rx * num_tx * num_bounces * num_paths],
.freq_shift = new float[num_rx * num_tx * num_bounces * num_paths]
};
+ // Output rays information
+ RaysInfo raysInfo_los = {
+ .rays = new Ray[num_rx * num_tx],
+ .rays_active = new uint8_t[num_rx * num_tx / 8 + 1]
+ };
+ RaysInfo raysInfo_scat = {
+ .rays = new Ray[num_rx * num_tx * (num_bounces + 1) * num_paths],
+ .rays_active = new uint8_t[num_rx * num_tx * (num_bounces + 1) * num_paths / 8 + 1]
+ };
// Call the C function
compute_paths(
- mesh_filepath.c_str(),
- (const float*)rx_pos_info.ptr, // Rx positions
- (const float*)tx_pos_info.ptr, // Tx positions
- (const float*)rx_vel_info.ptr, // Rx velocities
- (const float*)tx_vel_info.ptr, // Tx velocities
+ &scene, // Scene
+ (Vec3*)rx_pos_info.ptr, // Rx positions
+ (Vec3*)tx_pos_info.ptr, // Tx positions
+ (Vec3*)rx_vel_info.ptr, // Rx velocities
+ (Vec3*)tx_vel_info.ptr, // Tx velocities
carrier_frequency, // Carrier frequency in GHz
(size_t)num_rx,
(size_t)num_tx,
(size_t)num_paths,
(size_t)num_bounces,
- &los,
- &scatter
+ &chanInfo_los, // Channel info for LOS
+ &raysInfo_los, // Rays info for LOS
+ &chanInfo_scat, // Channel info for scatter
+ &raysInfo_scat // Rays info for scatter
);
+ // Free the rays info (TODO remove when RaysInfo is made optional in compute_paths)
+ delete[] raysInfo_los.rays;
+ delete[] raysInfo_los.rays_active;
+ delete[] raysInfo_scat.rays;
+ delete[] raysInfo_scat.rays_active;
+
+ // Free the scene
+ free_scene(&scene);
+
// Wrap the results into Python objects
return std::make_tuple(
- PathsInfoPython(los, num_rx, num_tx),
- PathsInfoPython(scatter, num_rx, num_tx)
+ ChannelInfoPython(chanInfo_los, num_rx, num_tx),
+ ChannelInfoPython(chanInfo_scat, num_rx, num_tx)
);
}
PYBIND11_MODULE(rt, m) {
- py::class_<PathsInfoPython>(m, "PathsInfo")
- .def_readonly("num_paths", &PathsInfoPython::num_paths)
- .def_readonly("directions_rx", &PathsInfoPython::directions_rx)
- .def_readonly("directions_tx", &PathsInfoPython::directions_tx)
- .def_readonly("a_te", &PathsInfoPython::a_te)
- .def_readonly("a_tm", &PathsInfoPython::a_tm)
- .def_readonly("tau", &PathsInfoPython::tau)
- .def_readonly("freq_shift", &PathsInfoPython::freq_shift);
+ py::class_<ChannelInfoPython>(m, "PathsInfo")
+ .def_readonly("num_paths", &ChannelInfoPython::num_paths)
+ .def_readonly("directions_rx", &ChannelInfoPython::directions_rx)
+ .def_readonly("directions_tx", &ChannelInfoPython::directions_tx)
+ .def_readonly("a_te", &ChannelInfoPython::a_te)
+ .def_readonly("a_tm", &ChannelInfoPython::a_tm)
+ .def_readonly("tau", &ChannelInfoPython::tau)
+ .def_readonly("freq_shift", &ChannelInfoPython::freq_shift);
// TODO write a proper docstring
m.def("compute_paths", &compute_paths_wrapper, "Compute gains and delays",
diff --git a/inc/scene.h b/inc/scene.h
@@ -5,6 +5,7 @@
#include "vec3.h" /* for Vec3 */
#include <stdint.h> /* for uint32_t */
+#include <stdlib.h> /* for free */
typedef struct {
/* Number of vertices */
@@ -64,6 +65,26 @@ typedef struct {
uint8_t s3_alpha;
} Material;
+/** Free the memory allocated for a mesh fields.
+ *
+ * \param mesh pointer to the mesh to free
+ */
+static inline void free_mesh(Mesh* mesh) {
+ free(mesh->vs);
+ free(mesh->is);
+ free(mesh->ns);
+}
+/** Deep free the scene. Frees all the meshes.
+ *
+ * \param scene pointer to the scene to free
+ */
+static inline void free_scene(Scene* scene) {
+ for (uint32_t i = 0; i < scene->num_meshes; i++) {
+ free_mesh(&scene->meshes[i]);
+ }
+ free(scene->meshes);
+}
+
/** Save a scene to a HRT file. (See README for details)
*
* NOTE: This function does not save the normals of the triangles (Mesh.ns field).
diff --git a/test/__init__.py b/test/__init__.py
diff --git a/test/test.py b/test/test.py
@@ -1,8 +1,11 @@
import numpy as np
-from rt import compute_paths
+
+import sys, os
+sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
+import rt
# Define inputs
-mesh_filepath = __file__[:__file__.rfind('/') + 1] + 'scenes/simple_reflector.hrt'
+mesh_filepath = __file__[:__file__.rfind('/') + 1] + '../scenes/simple_reflector.hrt'
rx_positions = np.array([[0., 0., .15]], dtype=np.float64)
tx_positions = np.array([[0., 0., .151]], dtype=np.float64)
rx_velocities = np.array([[0., 0., 0.]], dtype=np.float64)
@@ -14,7 +17,7 @@ num_paths = 10000
num_bounces = 3
# Call compute_paths
-los, scatter = compute_paths(
+los, scatter = rt.compute_paths(
mesh_filepath,
rx_positions,
tx_positions,