diff --git a/README.md b/README.md index 79672c71..c1ae2a02 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,6 @@ And more: - Converting to custom binary output - Downsampling - Writing to PCD file -- Optional Gaussian noise (see [documentation](docs/GaussianNoise.md)) ## Usage @@ -68,7 +67,7 @@ Build instructions: ## Building on Windows -1. Install [CUDA Toolkit](https://developer.nvidia.com/cuda-downloads) 11.2+. +1. Install [CUDA Toolkit](https://developer.nvidia.com/cuda-downloads) 11.4.4+. 2. Download [NVidia OptiX](https://developer.nvidia.com/designworks/optix/downloads/legacy) 7.2. - use the default location or set environment variable `OptiX_INSTALL_DIR` 3. Install [PCL](https://pointclouds.org/) 1.12: diff --git a/docs/GaussianNoise.md b/docs/GaussianNoise.md deleted file mode 100644 index 288bd5dc..00000000 --- a/docs/GaussianNoise.md +++ /dev/null @@ -1,116 +0,0 @@ -# Gaussian noise - -Robotec GPU Lidar (RGL) allows introducing Gaussian noise which models the naturally present noise of the physical devices. - -Gaussian noise is described by the following formula: - -![Gausian_noise_formula](image/gaussian_noise.gif) - -It is parametrized by these two values: -- μ - mean value -- σ - standard deviation - -## Supported noise types - -The following table presents concisely all kinds of Gaussian noise available in RGL. -The next chapters describe them in greater detail. - -| Noise type | Visualization | -|------------|---------------| -| **Ray-based angular noise:**
  • Rotate rays around Y-axis of the lidar
  • This kind of noise intends to model the noise in lidar's rotational speed |![Angular ray 2](image/Angular_ray_2.png) | -| **Hitpoint-based angular noise**
  • Rotate hitpoints around Y-axis of the lidar
  • This is different than rotating rays! Think of the effect on hitpoints on surfaces near-parallel to the ray
  • This kind of noise could model e.g. error in reading position of the rotated laser or sensor | ![Angular hitpoint 3](image/Angular_hitpoint_3.png) | -| **Distance noise**
  • This kind of noise can model e.g. error in measuring time-of-flight | ![Distance noise 3](image/Distance_3.png) | - -### Current limitation -Although ray-based and hitpoint based angular noise may occur independently in the real world, -the current implementation treats them as mutually exclusive - only one can be active at a time. -This limitation may be removed in the future. - -# Noise configuration API - -Noise parameters can be configured using `rgl_lidar_set_gaussian_noise_params` API call. - -| Parameter name | Field | Description | -|----------------------------------------|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------| -| `angular_noise_type` | `rgl_angular_noise_type_t` | Angular noise type selection enum. More details below | -| `angular_noise_stddev` | `float` | Angular noise standard deviation in radians | -| `angular_noise_mean` | `float` | Angular noise mean in radians | -| `distance_noise_stddev_base` | `float` | Distance noise base in meters. Represented as ![sigma_base](image/distance_noise_sigma_base.gif) in [Distance noise](#distance-noise) chapter | -| `distance_noise_stddev_rise_per_meter` | `float` | Distance noise base in meters. Represented as ![sigma_slope](image/distance_noise_sigma_slope.gif) in [Distance noise](#distance-noise) chapter | -| `distance_noise_mean` | `float` | Distance noise mean in meters | - -### `rgl_angular_noise_type_t` possible values - -| Field name | Value | Description | -|------------------------------|---------------------|------------- | -| RAY_BASED | `0` | Ray-based angular noise. For more information check the [Ray-based angular noise](#ray-based-angular-noise) chapter | -| HITPOINT_BASED | `1` | Hitpoint-based angular noise. For more information check the [Hitpoint based angular noise](#hitpoint-based-angular-noise) chapter | - - -## Ray-based angular noise - -This type of noise applies angular noise to the rays **before raycasting**. -When this type of noise is applied, points stay on the obstacle surface - -| Step | Visualization | -|--------------------------|---------------------------------------------| -|Rays are provided by the user via RGL API| ![Angular ray](image/Angular_ray_1.png)| -|Angular noise is applied to rays | ![Angular ray](image/Angular_ray_2.png)| -|Raytracing is performed using noised rays. Hitpoints are produced | ![Angular ray](image/Angular_ray_3.png)| -|Hitpoints with ray-based noise are sent for further processing| ![Angular ray](image/Angular_ray_4.png)| - -## Hitpoint-based angular noise - -This type of noise adds angular noise to already computed hitpoints. -In other words, it is a rotation of each hitpoint around LiDAR's origin. -When this type of noise is applied, points may be no longer on the obstacle surface - -| Step | Visualization | -|--------------------------|---------------------------------------------| -|Rays are provided by the user via RGL API| ![Angular hitpoint](image/Angular_hitpoint_1.png)| -|Raycasting is performed using user-provided rays. Hitpoints are produced | ![Angular hitpoint](image/Angular_hitpoint_2.png)| -|Hitpoints are rotated by the noise value| ![Angular hitpoint](image/Angular_hitpoint_3.png)| -|Hitpoints with hitpoint-based noise are sent for further processing| ![Angular hitpoint](image/Angular_hitpoint_4.png)| - -## Distance noise - -This kind of noise changes the distance between hitpoint and lidar's origin. - -Standard deviation can depend (increase linearly) on the point's distance from the sensor origin. - -Overall standard deviation of the distance error is computed as follows: - -![distance sigma formula](image/distance_stdev.gif) - -where - -|symbol| description| -|------|------------| -|![sigma_distance](image/distance_noise_sigma_distance.gif)| computed distance standard deviation applied to hitpoints | -|![sigma_base](image/distance_noise_sigma_base.gif)| base value of distance standard deviation (configurable) | -|![d](image/distance_noise_d.gif)| current points distance from sensor origin | -|![sigma_slope](image/distance_noise_sigma_slope.gif)| rise of the standard deviation per 1 meter of distance (configurable) | - -| Step | Visualization | -|--------------------------|---------------------------------------------| -|Ray are provided by the user via RGL API| ![Distance](image/Distance_1.png)| -|Raycasting is performed. Hitpoints are produced | ![Distance](image/Distance_2.png)| -|Hitpoints distance is changed by noise value| ![Distance](image/Distance_3.png)| -|Hitpoints with distance noise are sent for further processing| ![Distance](image/Distance_4.png)| - -## Details of the Gaussian noise in RGL pipeline - -Noise application steps are marked in **bold**. All of them are optional. - -1. Ray poses are provided by the user -1. **Angular noise is added to the rays** -1. Nvidia OptiX uses noised ray poses to perform raycasting operations -1. Two point clouds are produced (note: subject to change in the future) - - one in the world coordinate system - for visualization - - second in the LiDARs local coordinate system - actual data -1. **Angular noise is applied to both point clouds** -1. **Distance noise is applied to both point clouds** -1. Non-hit points are removed from the point clouds (in the future, this will be done before applying hitpoint based noise) -1. Point cloud data is converted to the final binary format to be sent via ROS topics - -![RGL pipeline](image/RGL_full_pipeline.png) diff --git a/docs/Usage.md b/docs/Usage.md index c3bb0029..1b4b79c2 100644 --- a/docs/Usage.md +++ b/docs/Usage.md @@ -72,44 +72,45 @@ Full source code can be found [here](../test/src/apiReadmeExample.cpp) ```c // Create a mesh -rgl_mesh_t cube_mesh = rgl_mesh_create(/* arguments skipped for the sake of brevity */); +rgl_mesh_t cube_mesh = nullptr; +rgl_mesh_create(&cube_mesh, /* remaining arguments skipped for the sake of brevity */); // Put an entity on the default scene -rgl_entity_t cube_entity = 0; -EXPECT_RGL_SUCCESS(rgl_entity_create(&cube_entity, NULL, cube_mesh)); +rgl_entity_t cube_entity = nullptr; +rgl_entity_create(&cube_entity, nullptr, cube_mesh); // Set position of the cube entity to (0, 0, 5) rgl_mat3x4f entity_tf = { .value = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, - { 0, 0, 1, 5 } } + { 0, 0, 1, 5 }} }; -EXPECT_RGL_SUCCESS(rgl_entity_set_pose(cube_entity, &entity_tf)); +rgl_entity_set_pose(cube_entity, &entity_tf); // Create a graph representation of a lidar that sends 1 ray and is situated at (x,y,z) = (0, 0, 0), facing positive Z rgl_mat3x4f ray_tf = { .value = { { 1, 0, 0, 0 }, { 0, 1, 0, 0 }, - { 0, 0, 1, 0 },} + { 0, 0, 1, 0 }} }; rgl_node_t useRays = nullptr, raytrace = nullptr; -EXPECT_RGL_SUCCESS(rgl_node_rays_from_mat3x4f(&useRays, &ray_tf, 1)); -EXPECT_RGL_SUCCESS(rgl_node_raytrace(&raytrace, nullptr, 1000)); -EXPECT_RGL_SUCCESS(rgl_graph_node_add_child(useRays, raytrace)); +rgl_node_rays_from_mat3x4f(&useRays, &ray_tf, 1); +rgl_node_raytrace(&raytrace, nullptr, 1000); +rgl_graph_node_add_child(useRays, raytrace); // you can run the graph using any one of its nodes -EXPECT_RGL_SUCCESS(rgl_graph_run(raytrace)); +rgl_graph_run(raytrace); // Wait for the Graph to run (if needed) and collect results -int32_t hitpoint_count = 0; -int32_t size; -rgl_vec3f results[1] = { 0 }; -EXPECT_RGL_SUCCESS(rgl_graph_get_result_size(raytrace, RGL_FIELD_XYZ_F32, &hitpoint_count, &size)); -EXPECT_RGL_SUCCESS(rgl_graph_get_result_data(raytrace, RGL_FIELD_XYZ_F32, &results)); +int32_t hitpoint_count; +int32_t point_size; +rgl_vec3f results[1]; +rgl_graph_get_result_size(raytrace, RGL_FIELD_XYZ_F32, &hitpoint_count, &point_size); +rgl_graph_get_result_data(raytrace, RGL_FIELD_XYZ_F32, &results); printf("Got %d hitpoint(s)\n", hitpoint_count); for (int i = 0; i < hitpoint_count; ++i) { diff --git a/docs/image/Angular_hitpoint_1.png b/docs/image/Angular_hitpoint_1.png deleted file mode 100644 index 8218e055..00000000 Binary files a/docs/image/Angular_hitpoint_1.png and /dev/null differ diff --git a/docs/image/Angular_hitpoint_2.png b/docs/image/Angular_hitpoint_2.png deleted file mode 100644 index 68d53c09..00000000 Binary files a/docs/image/Angular_hitpoint_2.png and /dev/null differ diff --git a/docs/image/Angular_hitpoint_3.png b/docs/image/Angular_hitpoint_3.png deleted file mode 100644 index 3aba0d0e..00000000 Binary files a/docs/image/Angular_hitpoint_3.png and /dev/null differ diff --git a/docs/image/Angular_hitpoint_4.png b/docs/image/Angular_hitpoint_4.png deleted file mode 100644 index b392e792..00000000 Binary files a/docs/image/Angular_hitpoint_4.png and /dev/null differ diff --git a/docs/image/Angular_ray_1.png b/docs/image/Angular_ray_1.png deleted file mode 100644 index c3f25dcb..00000000 Binary files a/docs/image/Angular_ray_1.png and /dev/null differ diff --git a/docs/image/Angular_ray_2.png b/docs/image/Angular_ray_2.png deleted file mode 100644 index f7796805..00000000 Binary files a/docs/image/Angular_ray_2.png and /dev/null differ diff --git a/docs/image/Angular_ray_3.png b/docs/image/Angular_ray_3.png deleted file mode 100644 index bc916531..00000000 Binary files a/docs/image/Angular_ray_3.png and /dev/null differ diff --git a/docs/image/Angular_ray_4.png b/docs/image/Angular_ray_4.png deleted file mode 100644 index 2672b943..00000000 Binary files a/docs/image/Angular_ray_4.png and /dev/null differ diff --git a/docs/image/Distance_1.png b/docs/image/Distance_1.png deleted file mode 100644 index c1ae55ae..00000000 Binary files a/docs/image/Distance_1.png and /dev/null differ diff --git a/docs/image/Distance_2.png b/docs/image/Distance_2.png deleted file mode 100644 index 495f0c7c..00000000 Binary files a/docs/image/Distance_2.png and /dev/null differ diff --git a/docs/image/Distance_3.png b/docs/image/Distance_3.png deleted file mode 100644 index 114f98c3..00000000 Binary files a/docs/image/Distance_3.png and /dev/null differ diff --git a/docs/image/Distance_4.png b/docs/image/Distance_4.png deleted file mode 100644 index dcdc48be..00000000 Binary files a/docs/image/Distance_4.png and /dev/null differ diff --git a/docs/image/distance_noise_d.gif b/docs/image/distance_noise_d.gif deleted file mode 100644 index 5b5cbbff..00000000 Binary files a/docs/image/distance_noise_d.gif and /dev/null differ diff --git a/docs/image/distance_noise_sigma_base.gif b/docs/image/distance_noise_sigma_base.gif deleted file mode 100644 index 279519bf..00000000 Binary files a/docs/image/distance_noise_sigma_base.gif and /dev/null differ diff --git a/docs/image/distance_noise_sigma_distance.gif b/docs/image/distance_noise_sigma_distance.gif deleted file mode 100644 index f9cda704..00000000 Binary files a/docs/image/distance_noise_sigma_distance.gif and /dev/null differ diff --git a/docs/image/distance_noise_sigma_slope.gif b/docs/image/distance_noise_sigma_slope.gif deleted file mode 100644 index 56d655a6..00000000 Binary files a/docs/image/distance_noise_sigma_slope.gif and /dev/null differ diff --git a/docs/image/distance_stdev.gif b/docs/image/distance_stdev.gif deleted file mode 100644 index 6b022b3f..00000000 Binary files a/docs/image/distance_stdev.gif and /dev/null differ diff --git a/docs/image/gaussian_noise.gif b/docs/image/gaussian_noise.gif deleted file mode 100644 index 7e71b503..00000000 Binary files a/docs/image/gaussian_noise.gif and /dev/null differ diff --git a/src/api/api.cpp b/src/api/api.cpp index d1cef87d..7a0e79c5 100644 --- a/src/api/api.cpp +++ b/src/api/api.cpp @@ -154,6 +154,7 @@ rgl_get_version_info(int32_t* out_major, int32_t* out_minor, int32_t* out_patch) // 0.10.0: entities can now share meshes // 0.10.1: API const correctness, added INVALID_OBJECT error, minor internal changes // 0.10.2: Fixed Lidar::getResults writing too many bytes + // 0.11.0: implement Graph API (Gaussian noise temporarily removed) auto status = rglSafeCall([&]() { RGL_DEBUG("rgl_get_version_info(out_major={}, out_minor={}, out_patch={})", (void*) out_major, (void*) out_minor, (void*) out_patch); diff --git a/test/src/apiReadmeExample.cpp b/test/src/apiReadmeExample.cpp index c417cb53..19e2a5fb 100644 --- a/test/src/apiReadmeExample.cpp +++ b/test/src/apiReadmeExample.cpp @@ -8,11 +8,12 @@ TEST(EndToEnd, ReadmeExample) EXPECT_RGL_SUCCESS(rgl_get_version_info(&major, &minor, &patch)); printf("RGL version: %d.%d.%d\n", major, minor, patch); + // Create a mesh by using helper function from test/include/scenes.hpp rgl_mesh_t cube_mesh = makeCubeMesh(); // Put an entity on the default scene - rgl_entity_t cube_entity = 0; - EXPECT_RGL_SUCCESS(rgl_entity_create(&cube_entity, NULL, cube_mesh)); + rgl_entity_t cube_entity = nullptr; + EXPECT_RGL_SUCCESS(rgl_entity_create(&cube_entity, nullptr, cube_mesh)); // Set position of the cube entity to (0, 0, 5) rgl_mat3x4f entity_tf = { @@ -42,10 +43,10 @@ TEST(EndToEnd, ReadmeExample) EXPECT_RGL_SUCCESS(rgl_graph_run(raytrace)); // Wait for the Graph to run (if needed) and collect results - int32_t hitpoint_count = 0; - int32_t size; - rgl_vec3f results[1] = { 0 }; - EXPECT_RGL_SUCCESS(rgl_graph_get_result_size(raytrace, RGL_FIELD_XYZ_F32, &hitpoint_count, &size)); + int32_t hitpoint_count; + int32_t point_size; + rgl_vec3f results[1]; + EXPECT_RGL_SUCCESS(rgl_graph_get_result_size(raytrace, RGL_FIELD_XYZ_F32, &hitpoint_count, &point_size)); EXPECT_RGL_SUCCESS(rgl_graph_get_result_data(raytrace, RGL_FIELD_XYZ_F32, &results)); printf("Got %d hitpoint(s)\n", hitpoint_count);