scenario_simulator_v2 C++ API
raycaster.hpp
Go to the documentation of this file.
1 // Copyright 2015 TIER IV, Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef SIMPLE_SENSOR_SIMULATOR__SENSOR_SIMULATION__LIDAR__RAYCASTER_HPP_
16 #define SIMPLE_SENSOR_SIMULATOR__SENSOR_SIMULATION__LIDAR__RAYCASTER_HPP_
17 
18 #include <embree4/rtcore.h>
19 #include <pcl_conversions/pcl_conversions.h>
20 
21 #include <algorithm>
23 #include <geometry_msgs/msg/pose.hpp>
24 #include <memory>
25 #include <optional>
26 #include <random>
29 #include <string>
30 #include <utility>
31 #include <vector>
32 
34 {
35 class Raycaster
36 {
37 public:
38  Raycaster();
39  explicit Raycaster(std::string embree_config);
40  ~Raycaster();
41 
42  struct Entity
43  {
45  std::unique_ptr<primitives::Primitive> primitive;
46  std::optional<uint32_t> geometry_id;
47 
48  explicit Entity(const traffic_simulator_msgs::EntityStatus & status);
49 
50  const std::string & name() const { return entity_status.name(); }
51  };
52 
54  {
55  pcl::PointCloud<pcl::PointXYZI>::Ptr cloud;
56  std::vector<size_t> point_to_entity_index;
57  const std::vector<Entity> & raycast_entities;
58 
59  explicit RaycastResult(const std::vector<Entity> & entities)
60  : cloud(new pcl::PointCloud<pcl::PointXYZI>), raycast_entities(entities)
61  {
62  }
63 
64  std::set<std::string> getDetectedEntityNames() const
65  {
66  std::set<std::string> detected_entity_names;
67  for (const auto & entity_idx : point_to_entity_index) {
68  detected_entity_names.insert(raycast_entities[entity_idx].name());
69  }
70  return detected_entity_names;
71  }
72  };
73 
74  RaycastResult raycast(
75  const geometry_msgs::msg::Pose & origin, std::vector<Entity> & entities,
76  double max_distance = 300, double min_distance = 0);
77  void setDirection(
78  const simulation_api_schema::LidarConfiguration & configuration,
79  double horizontal_angle_start = 0, double horizontal_angle_end = 2 * M_PI);
80 
81 private:
82  std::vector<geometry_msgs::msg::Quaternion> getDirections(
83  const std::vector<double> & vertical_angles, double horizontal_angle_start,
84  double horizontal_angle_end, double horizontal_resolution);
85  std::vector<geometry_msgs::msg::Quaternion> directions_;
86  double previous_horizontal_angle_start_;
87  double previous_horizontal_angle_end_;
88  double previous_horizontal_resolution_;
89  std::vector<double> previous_vertical_angles_;
90  RTCDevice device_;
91  RTCScene scene_;
92  std::random_device seed_gen_;
93  std::default_random_engine engine_;
94  std::vector<Eigen::Matrix3d> rotation_matrices_;
95 
96  void intersect(
97  pcl::PointCloud<pcl::PointXYZI>::Ptr cloud, const geometry_msgs::msg::Pose & origin,
98  std::vector<uint32_t> & point_geometry_ids, double max_distance, double min_distance)
99  {
100  const auto orientation_matrix = math::geometry::getRotationMatrix(origin.orientation);
101  for (unsigned int i = 0; i < rotation_matrices_.size(); ++i) {
102  RTCRayHit rayhit = {};
103  rayhit.ray.org_x = origin.position.x;
104  rayhit.ray.org_y = origin.position.y;
105  rayhit.ray.org_z = origin.position.z;
106  // make raycast interact with all objects
107  rayhit.ray.mask = 0b11111111'11111111'11111111'11111111;
108  rayhit.ray.tfar = max_distance;
109  rayhit.ray.tnear = min_distance;
110  rayhit.ray.flags = false;
111 
112  const auto & ray_direction = rotation_matrices_.at(i);
113  const auto rotation_mat = orientation_matrix * ray_direction;
114  rayhit.ray.dir_x = rotation_mat(0);
115  rayhit.ray.dir_y = rotation_mat(1);
116  rayhit.ray.dir_z = rotation_mat(2);
117  rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
118  rtcIntersect1(scene_, &rayhit);
119 
120  if (rayhit.hit.geomID != RTC_INVALID_GEOMETRY_ID) {
121  double distance = rayhit.ray.tfar;
122  pcl::PointXYZI p;
123  {
124  p.x = ray_direction(0) * distance;
125  p.y = ray_direction(1) * distance;
126  p.z = ray_direction(2) * distance;
127  }
128  cloud->emplace_back(p);
129  point_geometry_ids.push_back(rayhit.hit.geomID);
130  }
131  }
132  }
133 };
134 } // namespace simple_sensor_simulator
135 
136 #endif // SIMPLE_SENSOR_SIMULATOR__SENSOR_SIMULATION__LIDAR__RAYCASTER_HPP_
Definition: raycaster.hpp:36
~Raycaster()
Definition: raycaster.cpp:55
Raycaster()
Definition: raycaster.cpp:45
void setDirection(const simulation_api_schema::LidarConfiguration &configuration, double horizontal_angle_start=0, double horizontal_angle_end=2 *M_PI)
Definition: raycaster.cpp:61
RaycastResult raycast(const geometry_msgs::msg::Pose &origin, std::vector< Entity > &entities, double max_distance=300, double min_distance=0)
Definition: raycaster.cpp:110
auto getRotationMatrix(T quat) -> Eigen::Matrix3d
Definition: get_rotation_matrix.hpp:33
Definition: constants.hpp:19
auto distance(const geometry_msgs::Pose &pose1, const geometry_msgs::Pose &pose2)
Definition: detection_sensor.cpp:44
geometry_msgs::msg::Pose Pose
Definition: lanelet_wrapper.hpp:66
std::string string
Definition: junit5.hpp:26
traffic_simulator_msgs::EntityStatus EntityStatus
Definition: helper_functions.hpp:32
Definition: raycaster.hpp:43
const traffic_simulator_msgs::EntityStatus & entity_status
Definition: raycaster.hpp:44
const std::string & name() const
Definition: raycaster.hpp:50
std::optional< uint32_t > geometry_id
Definition: raycaster.hpp:46
std::unique_ptr< primitives::Primitive > primitive
Definition: raycaster.hpp:45
Entity(const traffic_simulator_msgs::EntityStatus &status)
Definition: raycaster.cpp:26
RaycastResult(const std::vector< Entity > &entities)
Definition: raycaster.hpp:59
std::set< std::string > getDetectedEntityNames() const
Definition: raycaster.hpp:64
const std::vector< Entity > & raycast_entities
Definition: raycaster.hpp:57
pcl::PointCloud< pcl::PointXYZI >::Ptr cloud
Definition: raycaster.hpp:55
std::vector< size_t > point_to_entity_index
Definition: raycaster.hpp:56