scenario_simulator_v2 C++ API
entity_manager.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 TRAFFIC_SIMULATOR__ENTITY__ENTITY_MANAGER_HPP_
16 #define TRAFFIC_SIMULATOR__ENTITY__ENTITY_MANAGER_HPP_
17 
18 #include <tf2_ros/static_transform_broadcaster.h>
19 #include <tf2_ros/transform_broadcaster.h>
20 
21 #include <get_parameter/get_parameter.hpp>
28 #include <traffic_simulator_msgs/msg/entity_status_with_trajectory_array.hpp>
29 
30 namespace traffic_simulator
31 {
32 namespace entity
33 {
34 class LaneletMarkerQoS : public rclcpp::QoS
35 {
36 public:
37  explicit LaneletMarkerQoS(std::size_t depth = 1) : rclcpp::QoS(depth) { transient_local(); }
38 };
39 
40 class EntityMarkerQoS : public rclcpp::QoS
41 {
42 public:
43  explicit EntityMarkerQoS(std::size_t depth = 100) : rclcpp::QoS(depth) {}
44 };
45 
47 {
48  using EntityStatusWithTrajectoryArray =
49  traffic_simulator_msgs::msg::EntityStatusWithTrajectoryArray;
50  using MarkerArray = visualization_msgs::msg::MarkerArray;
51 
52 public:
53  template <class NodeT, class AllocatorT = std::allocator<void>>
54  explicit EntityManager(
55  NodeT && node, const Configuration & configuration,
56  const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr & node_parameters)
57  : configuration_(configuration),
58  clock_ptr_(node->get_clock()),
59  node_parameters_(node_parameters),
60  broadcaster_(node),
61  base_link_broadcaster_(node),
62  entity_status_array_pub_ptr_(rclcpp::create_publisher<EntityStatusWithTrajectoryArray>(
63  node, "entity/status", EntityMarkerQoS(),
64  rclcpp::PublisherOptionsWithAllocator<AllocatorT>())),
65  lanelet_marker_pub_ptr_(rclcpp::create_publisher<MarkerArray>(
66  node, "lanelet/marker", LaneletMarkerQoS(),
67  rclcpp::PublisherOptionsWithAllocator<AllocatorT>())),
68  hdmap_utils_ptr_(std::make_shared<hdmap_utils::HdMapUtils>(
69  configuration_.lanelet2_map_path(), getOrigin(*node))),
70  markers_raw_(hdmap_utils_ptr_->generateMarker())
71  {
73  }
74 
75  ~EntityManager() = default;
76 
77  // global
83  auto setTrafficLights(const std::shared_ptr<TrafficLights> & traffic_lights_ptr) -> void;
84 
85  auto setVerbose(const bool verbose) -> void;
86 
87  auto startNpcLogic(const double current_time) -> void;
88 
89  auto isNpcLogicStarted() const -> bool;
90 
91  auto makeDebugMarker() const -> visualization_msgs::msg::MarkerArray;
92 
93  // update
94  auto update(const double current_time, const double step_time) -> void;
95 
96  auto updateNpcLogic(const std::string & name, const double current_time, const double step_time)
97  -> const CanonicalizedEntityStatus &;
98 
99  auto updateHdmapMarker() const -> void;
100 
101  auto broadcastEntityTransform() -> void;
102 
103  auto broadcastTransform(
104  const geometry_msgs::msg::PoseStamped & pose, const bool static_transform = true) -> void;
105 
106  // entities, ego - spawn
107  template <typename EntityType, typename PoseType, typename ParametersType, typename... Ts>
109  const std::string & name, const PoseType & pose, const ParametersType & parameters,
110  const double current_time, Ts &&... xs) -> entity::EntityBase &
111  {
112  static_assert(
113  std::disjunction<
114  std::is_same<PoseType, CanonicalizedLaneletPose>,
115  std::is_same<PoseType, geometry_msgs::msg::Pose>>::value,
116  "Pose must be of type CanonicalizedLaneletPose or geometry_msgs::msg::Pose");
117 
119  EntityStatus entity_status;
120 
121  if constexpr (std::is_same_v<std::decay_t<EntityType>, EgoEntity>) {
122  if (isAnyEgoSpawned()) {
123  THROW_SEMANTIC_ERROR("multi ego simulation does not support yet");
124  } else {
125  entity_status.type.type = traffic_simulator_msgs::msg::EntityType::EGO;
126  }
127  } else if constexpr (std::is_same_v<std::decay_t<EntityType>, VehicleEntity>) {
128  entity_status.type.type = traffic_simulator_msgs::msg::EntityType::VEHICLE;
129  } else if constexpr (std::is_same_v<std::decay_t<EntityType>, PedestrianEntity>) {
130  entity_status.type.type = traffic_simulator_msgs::msg::EntityType::PEDESTRIAN;
131  } else {
132  entity_status.type.type = traffic_simulator_msgs::msg::EntityType::MISC_OBJECT;
133  }
134 
135  entity_status.subtype = parameters.subtype;
136  entity_status.time = current_time;
137  entity_status.name = name;
138  entity_status.bounding_box = parameters.bounding_box;
139  entity_status.action_status = traffic_simulator_msgs::msg::ActionStatus();
140  entity_status.action_status.current_action = "waiting for initialize";
141 
142  const auto include_crosswalk = [](const auto & entity_type) {
143  return (traffic_simulator_msgs::msg::EntityType::PEDESTRIAN == entity_type.type) ||
144  (traffic_simulator_msgs::msg::EntityType::MISC_OBJECT == entity_type.type);
145  }(entity_status.type);
146 
147  const auto matching_distance = [](const auto & local_parameters) {
148  if constexpr (std::is_same_v<
149  std::decay_t<ParametersType>,
150  traffic_simulator_msgs::msg::VehicleParameters>) {
151  return std::max(
152  local_parameters.axles.front_axle.track_width,
153  local_parameters.axles.rear_axle.track_width) *
154  0.5 +
155  1.0;
156  } else {
157  return local_parameters.bounding_box.dimensions.y * 0.5 + 1.0;
158  }
159  }(parameters);
160 
161  if constexpr (std::is_same_v<std::decay_t<PoseType>, LaneletPose>) {
163  "LaneletPose is not supported type as pose argument. Only CanonicalizedLaneletPose and "
164  "msg::Pose are supported as pose argument of EntityManager::spawnEntity().");
165  } else if constexpr (std::is_same_v<std::decay_t<PoseType>, CanonicalizedLaneletPose>) {
166  entity_status.pose = toMapPose(pose);
167  return CanonicalizedEntityStatus(entity_status, pose);
168  } else if constexpr (std::is_same_v<std::decay_t<PoseType>, geometry_msgs::msg::Pose>) {
169  entity_status.pose = pose;
170  const auto canonicalized_lanelet_pose = pose::toCanonicalizedLaneletPose(
171  pose, parameters.bounding_box, include_crosswalk, matching_distance);
172  return CanonicalizedEntityStatus(entity_status, canonicalized_lanelet_pose);
173  }
174  };
175 
176  if (const auto [iter, success] = entities_.emplace(
177  name, std::make_unique<EntityType>(
178  name, makeEntityStatus(), hdmap_utils_ptr_, parameters,
179  std::forward<decltype(xs)>(xs)...));
180  success) {
181  // FIXME: this ignores V2I traffic lights
182  iter->second->setTrafficLights(traffic_lights_ptr_->getConventionalTrafficLights());
183  return *(iter->second);
184  } else {
185  THROW_SEMANTIC_ERROR("Entity ", std::quoted(name), " is already exists.");
186  }
187  }
188 
189  // ego - checks, getters
190  auto getNumberOfEgo() const -> std::size_t;
191 
192  auto isAnyEgoSpawned() const -> bool;
193 
194  auto getFirstEgoName() const -> std::optional<std::string>;
195 
196  auto getEgoEntity(const std::string & name) -> entity::EgoEntity &;
197 
198  auto getEgoEntity(const std::string & name) const -> const entity::EgoEntity &;
199 
200  // entities - checks, getters
201  auto isEntityExist(const std::string & name) const -> bool;
202 
203  auto getEntityNames() const -> const std::vector<std::string>;
204 
205  auto getEntity(const std::string & name) -> entity::EntityBase &;
206 
207  auto getEntity(const std::string & name) const -> const entity::EntityBase &;
208 
209  auto getEntityPointer(const std::string & name) const -> std::shared_ptr<entity::EntityBase>;
210 
211  // entities - respawn, despawn, reset
220  auto resetBehaviorPlugin(const std::string & name, const std::string & behavior_plugin_name)
221  -> void;
222 
223  auto despawnEntity(const std::string & name) -> bool;
224 
225  // traffics, lanelet
226  auto getHdmapUtils() -> const std::shared_ptr<hdmap_utils::HdMapUtils> &;
227 
228  template <typename Node>
229  auto getOrigin(Node & node) const
230  {
231  geographic_msgs::msg::GeoPoint origin;
232  origin.latitude = common::getParameter<decltype(origin.latitude)>(
233  node.get_node_parameters_interface(), "origin_latitude");
234  origin.longitude = common::getParameter<decltype(origin.longitude)>(
235  node.get_node_parameters_interface(), "origin_longitude");
236  return origin;
237  }
238 
239  auto getObstacle(const std::string & name)
240  -> std::optional<traffic_simulator_msgs::msg::Obstacle>;
241 
242  auto getPedestrianParameters(const std::string & name) const
243  -> const traffic_simulator_msgs::msg::PedestrianParameters &;
244 
245  auto getVehicleParameters(const std::string & name) const
246  -> const traffic_simulator_msgs::msg::VehicleParameters &;
247 
248  auto getWaypoints(const std::string & name) -> traffic_simulator_msgs::msg::WaypointsArray;
249 
250  template <typename T>
251  auto getGoalPoses(const std::string & name) -> std::vector<T>
252  {
253  if constexpr (std::is_same_v<std::decay_t<T>, CanonicalizedLaneletPose>) {
254  if (not npc_logic_started_) {
255  return {};
256  } else {
257  return entities_.at(name)->getGoalPoses();
258  }
259  } else {
260  if (not npc_logic_started_) {
261  return {};
262  } else {
263  std::vector<geometry_msgs::msg::Pose> poses;
264  for (const auto & lanelet_pose : getGoalPoses<CanonicalizedLaneletPose>(name)) {
265  poses.push_back(pose::toMapPose(lanelet_pose));
266  }
267  return poses;
268  }
269  }
270  }
271 
272 private:
273  /* */ Configuration configuration_;
274 
275  const rclcpp::Clock::SharedPtr clock_ptr_;
276 
277  const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters_;
278 
279  /* */ tf2_ros::StaticTransformBroadcaster broadcaster_;
280 
281  /* */ tf2_ros::TransformBroadcaster base_link_broadcaster_;
282 
283  const rclcpp::Publisher<EntityStatusWithTrajectoryArray>::SharedPtr entity_status_array_pub_ptr_;
284 
285  const rclcpp::Publisher<MarkerArray>::SharedPtr lanelet_marker_pub_ptr_;
286 
287  /* */ std::unordered_map<std::string, std::shared_ptr<entity::EntityBase>> entities_;
288 
289  /* */ bool npc_logic_started_{false};
290 
291  /* */ std::shared_ptr<TrafficLights> traffic_lights_ptr_{nullptr};
292 
293  const std::shared_ptr<hdmap_utils::HdMapUtils> hdmap_utils_ptr_;
294 
295  /* */ MarkerArray markers_raw_;
296 };
297 } // namespace entity
298 } // namespace traffic_simulator
299 #endif // TRAFFIC_SIMULATOR__ENTITY__ENTITY_MANAGER_HPP_
Definition: ego_entity.hpp:35
Definition: entity_base.hpp:51
Definition: entity_manager.hpp:47
auto getGoalPoses(const std::string &name) -> std::vector< T >
Definition: entity_manager.hpp:251
auto update(const double current_time, const double step_time) -> void
Definition: entity_manager.cpp:60
auto isAnyEgoSpawned() const -> bool
Definition: entity_manager.cpp:222
auto despawnEntity(const std::string &name) -> bool
Definition: entity_manager.cpp:347
auto getEntityNames() const -> const std::vector< std::string >
Definition: entity_manager.cpp:268
auto getEgoEntity(const std::string &name) -> entity::EgoEntity &
Definition: entity_manager.cpp:239
auto resetBehaviorPlugin(const std::string &name, const std::string &behavior_plugin_name) -> void
Reset behavior plugin of the target entity. The internal behavior is to take over the various paramet...
Definition: entity_manager.cpp:313
auto updateHdmapMarker() const -> void
Definition: entity_manager.cpp:127
auto spawnEntity(const std::string &name, const PoseType &pose, const ParametersType &parameters, const double current_time, Ts &&... xs) -> entity::EntityBase &
Definition: entity_manager.hpp:108
auto getFirstEgoName() const -> std::optional< std::string >
Definition: entity_manager.cpp:229
auto getWaypoints(const std::string &name) -> traffic_simulator_msgs::msg::WaypointsArray
Definition: entity_manager.cpp:390
auto isNpcLogicStarted() const -> bool
Definition: entity_manager.cpp:48
auto broadcastTransform(const geometry_msgs::msg::PoseStamped &pose, const bool static_transform=true) -> void
Definition: entity_manager.cpp:193
EntityManager(NodeT &&node, const Configuration &configuration, const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr &node_parameters)
Definition: entity_manager.hpp:54
auto isEntityExist(const std::string &name) const -> bool
Definition: entity_manager.cpp:263
auto getHdmapUtils() -> const std::shared_ptr< hdmap_utils::HdMapUtils > &
Definition: entity_manager.cpp:353
auto getPedestrianParameters(const std::string &name) const -> const traffic_simulator_msgs::msg::PedestrianParameters &
Definition: entity_manager.cpp:368
auto getOrigin(Node &node) const
Definition: entity_manager.hpp:229
auto broadcastEntityTransform() -> void
Definition: entity_manager.cpp:139
auto setTrafficLights(const std::shared_ptr< TrafficLights > &traffic_lights_ptr) -> void
Definition: entity_manager.cpp:25
auto getEntity(const std::string &name) -> entity::EntityBase &
Definition: entity_manager.cpp:277
auto updateNpcLogic(const std::string &name, const double current_time, const double step_time) -> const CanonicalizedEntityStatus &
Definition: entity_manager.cpp:110
auto getVehicleParameters(const std::string &name) const -> const traffic_simulator_msgs::msg::VehicleParameters &
Definition: entity_manager.cpp:379
auto makeDebugMarker() const -> visualization_msgs::msg::MarkerArray
Definition: entity_manager.cpp:50
auto setVerbose(const bool verbose) -> void
Definition: entity_manager.cpp:31
auto startNpcLogic(const double current_time) -> void
Definition: entity_manager.cpp:39
auto getObstacle(const std::string &name) -> std::optional< traffic_simulator_msgs::msg::Obstacle >
Definition: entity_manager.cpp:358
auto getNumberOfEgo() const -> std::size_t
Definition: entity_manager.cpp:215
auto getEntityPointer(const std::string &name) const -> std::shared_ptr< entity::EntityBase >
Definition: entity_manager.cpp:295
Definition: entity_manager.hpp:41
EntityMarkerQoS(std::size_t depth=100)
Definition: entity_manager.hpp:43
Definition: entity_manager.hpp:35
LaneletMarkerQoS(std::size_t depth=1)
Definition: entity_manager.hpp:37
Definition: pedestrian_entity.hpp:34
Definition: vehicle_entity.hpp:37
Definition: entity_status.hpp:32
Definition: lanelet_pose.hpp:28
#define THROW_SYNTAX_ERROR(...)
Definition: exception.hpp:62
#define THROW_SEMANTIC_ERROR(...)
Definition: exception.hpp:59
Definition: cache.hpp:28
Definition: lanelet_wrapper.hpp:40
geometry_msgs::msg::Pose Pose
Definition: lanelet_wrapper.hpp:66
geometry_msgs::msg::PoseStamped PoseStamped
Definition: lanelet_wrapper.hpp:67
auto toCanonicalizedLaneletPose(const LaneletPose &lanelet_pose) -> std::optional< CanonicalizedLaneletPose >
Definition: pose.cpp:104
auto toMapPose(const CanonicalizedLaneletPose &lanelet_pose) -> geometry_msgs::msg::Pose
Definition: pose.cpp:87
Definition: api.hpp:32
traffic_simulator_msgs::msg::EntityType EntityType
Definition: entity_status.hpp:26
traffic_simulator_msgs::msg::LaneletPose LaneletPose
Definition: lanelet_pose.hpp:23
traffic_simulator_msgs::msg::EntityStatus EntityStatus
Definition: entity_status.hpp:25
Definition: junit5.hpp:25
std::string string
Definition: junit5.hpp:26
Definition: configuration.hpp:31
auto makeEntityStatus(traffic_simulator::lanelet_pose::CanonicalizedLaneletPose pose, traffic_simulator_msgs::msg::BoundingBox bbox, const double speed=0.0, const std::string name="default_entity_name", const uint8_t type=traffic_simulator_msgs::msg::EntityType::VEHICLE) -> traffic_simulator::EntityStatus
Definition: helper_functions.hpp:115