scenario_simulator_v2 C++ API
api.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__API__API_HPP_
16 #define TRAFFIC_SIMULATOR__API__API_HPP_
17 
18 #include <simulation_api_schema.pb.h>
19 
22 #include <std_msgs/msg/float64.hpp>
29 #include <traffic_simulator_msgs/msg/behavior_parameter.hpp>
30 
32 {
34 {
35  static auto autoware() noexcept -> const std::string &
36  {
37  static const std::string name = "Autoware";
38  return name;
39  }
40 };
41 
43 {
44 };
45 
47 {
48  static auto noBehavior() noexcept -> const std::string &
49  {
50  static const std::string name = "";
51  return name;
52  }
53 };
54 
55 class API
56 {
57 public:
58  template <typename NodeT, typename AllocatorT = std::allocator<void>, typename... Ts>
59  explicit API(NodeT && node, const Configuration & configuration, Ts &&... xs)
60  : configuration_(configuration),
61  node_parameters_(
62  rclcpp::node_interfaces::get_node_parameters_interface(std::forward<NodeT>(node))),
63  clock_pub_(rclcpp::create_publisher<rosgraph_msgs::msg::Clock>(
64  node, "/clock", rclcpp::QoS(rclcpp::KeepLast(1)).best_effort(),
65  rclcpp::PublisherOptionsWithAllocator<AllocatorT>())),
66  debug_marker_pub_(rclcpp::create_publisher<visualization_msgs::msg::MarkerArray>(
67  node, "debug_marker", rclcpp::QoS(100), rclcpp::PublisherOptionsWithAllocator<AllocatorT>())),
68  clock_(
69  common::getParameter<bool>(node_parameters_, "use_sim_time"),
70  std::forward<decltype(xs)>(xs)...),
71  zeromq_client_(
72  simulation_interface::protocol, configuration.simulator_host,
73  common::getParameter<int>(node_parameters_, "port", 5555)),
74  entity_manager_ptr_(
75  std::make_shared<entity::EntityManager>(node, configuration, node_parameters_)),
76  traffic_controller_ptr_(std::make_shared<traffic::TrafficController>(
77  [this](const std::string & name) { despawn(name); }, entity_manager_ptr_,
78  configuration.auto_sink_entity_types)),
79  traffic_lights_ptr_(std::make_shared<TrafficLights>(
80  node, entity_manager_ptr_->getHdmapUtils(),
81  common::getParameter<std::string>(
82  node_parameters_, "architecture_type", "awf/universe/20240605"))),
83  real_time_factor_subscriber_(rclcpp::create_subscription<std_msgs::msg::Float64>(
84  node, "/real_time_factor", rclcpp::QoS(rclcpp::KeepLast(1)).best_effort(),
85  [this](const std_msgs::msg::Float64 & message) {
86  return setSimulationStepTime(message.data);
87  }))
88  {
89  entity_manager_ptr_->setVerbose(configuration_.verbose);
90  entity_manager_ptr_->setTrafficLights(traffic_lights_ptr_);
91  if (not init()) {
92  throw common::SimulationError("Failed to initialize simulator by InitializeRequest");
93  }
94  }
95 
96  // global
97  template <typename ParameterT, typename... Ts>
98  auto getROS2Parameter(Ts &&... xs) const -> decltype(auto)
99  {
100  return common::getParameter<ParameterT>(node_parameters_, std::forward<Ts>(xs)...);
101  }
102 
103  auto init() -> bool;
104 
105  auto setVerbose(const bool verbose) -> void;
106 
107  auto setSimulationStepTime(const double step_time) -> bool;
108 
109  auto startNpcLogic() -> void;
110 
111  auto isNpcLogicStarted() const -> bool;
112 
113  auto getCurrentTime() const noexcept -> double;
114 
115  auto closeZMQConnection() -> void;
116 
117  // update
118  auto updateFrame() -> bool;
119 
120  // entities, ego - spawn
121  template <
122  typename PoseType, typename ParamsType,
123  typename = std::enable_if_t<std::disjunction_v<
124  std::is_same<std::decay_t<ParamsType>, traffic_simulator_msgs::msg::VehicleParameters>,
125  std::is_same<std::decay_t<ParamsType>, traffic_simulator_msgs::msg::PedestrianParameters>,
126  std::is_same<std::decay_t<ParamsType>, traffic_simulator_msgs::msg::MiscObjectParameters>>>>
127  auto spawn(
128  const std::string & name, const PoseType & pose, const ParamsType & parameters,
129  const std::string & behavior = "", const std::string & model3d = "") -> entity::EntityBase &
130  {
131  using VehicleParameters = traffic_simulator_msgs::msg::VehicleParameters;
132  using PedestrianParameters = traffic_simulator_msgs::msg::PedestrianParameters;
133  using MiscObjectParameters = traffic_simulator_msgs::msg::MiscObjectParameters;
134 
135  auto register_to_entity_manager = [&]() -> entity::EntityBase & {
136  if constexpr (std::is_same_v<ParamsType, VehicleParameters>) {
137  if (behavior == VehicleBehavior::autoware()) {
138  return entity_manager_ptr_->spawnEntity<entity::EgoEntity>(
139  name, pose, parameters, getCurrentTime(), configuration_, node_parameters_);
140  } else {
141  return entity_manager_ptr_->spawnEntity<entity::VehicleEntity>(
142  name, pose, parameters, getCurrentTime(),
143  behavior.empty() ? VehicleBehavior::defaultBehavior() : behavior);
144  }
145  } else if constexpr (std::is_same_v<ParamsType, PedestrianParameters>) {
146  return entity_manager_ptr_->spawnEntity<entity::PedestrianEntity>(
147  name, pose, parameters, getCurrentTime(),
148  behavior.empty() ? PedestrianBehavior::defaultBehavior() : behavior);
149  } else if constexpr (std::is_same_v<ParamsType, MiscObjectParameters>) {
150  return entity_manager_ptr_->spawnEntity<entity::MiscObjectEntity>(
151  name, pose, parameters, getCurrentTime());
152  }
153  };
154 
155  auto prepare_and_send_request = [&](const auto & entity, auto & request) -> bool {
156  simulation_interface::toProto(parameters, *request.mutable_parameters());
157  request.mutable_parameters()->set_name(name);
158  request.set_asset_key(model3d);
159  simulation_interface::toProto(entity.getMapPose(), *request.mutable_pose());
160  return zeromq_client_.call(request).result().success();
161  };
162 
163  auto register_to_environment_simulator = [&](const auto & entity) -> bool {
164  if (configuration_.standalone_mode) {
165  return true;
166  } else {
167  if constexpr (std::is_same_v<ParamsType, VehicleParameters>) {
168  simulation_api_schema::SpawnVehicleEntityRequest request;
169  request.set_is_ego(behavior == VehicleBehavior::autoware());
171  request.set_initial_speed(0.0);
172  return prepare_and_send_request(entity, request);
173  } else if constexpr (std::is_same_v<ParamsType, PedestrianParameters>) {
174  simulation_api_schema::SpawnPedestrianEntityRequest request;
175  return prepare_and_send_request(entity, request);
176  } else if constexpr (std::is_same_v<ParamsType, MiscObjectParameters>) {
177  simulation_api_schema::SpawnMiscObjectEntityRequest request;
178  return prepare_and_send_request(entity, request);
179  } else {
180  return false;
181  }
182  }
183  };
184 
185  auto & entity = register_to_entity_manager();
186  if (register_to_environment_simulator(entity)) {
187  return entity;
188  } else {
189  THROW_SEMANTIC_ERROR("Spawn entity ", std::quoted(name), " resulted in failure.");
190  }
191  }
192 
193  // sensors - attach
194  auto attachImuSensor(
195  const std::string &, const simulation_api_schema::ImuSensorConfiguration & configuration)
196  -> bool;
197 
199  const simulation_api_schema::PseudoTrafficLightDetectorConfiguration &) -> bool;
200 
201  auto attachLidarSensor(const simulation_api_schema::LidarConfiguration &) -> bool;
202 
203  auto attachLidarSensor(
204  const std::string &, const double lidar_sensor_delay,
206 
207  auto attachDetectionSensor(const simulation_api_schema::DetectionSensorConfiguration &) -> bool;
208 
210  const std::string &, double detection_sensor_range, bool detect_all_objects_in_range,
211  double pos_noise_stddev, int random_seed, double probability_of_lost,
212  double object_recognition_delay) -> bool;
213 
214  auto attachOccupancyGridSensor(const simulation_api_schema::OccupancyGridSensorConfiguration &)
215  -> bool;
216 
217  // ego - checks, getters
218  auto isAnyEgoSpawned() const -> bool;
219 
220  auto getFirstEgoName() const -> std::optional<std::string>;
221 
222  auto getEgoEntity(const std::string & name) -> entity::EgoEntity &;
223 
224  auto getEgoEntity(const std::string & name) const -> const entity::EgoEntity &;
225 
226  // entities - checks, getters
227  auto isEntityExist(const std::string & name) const -> bool;
228 
229  auto getEntityNames() const -> std::vector<std::string>;
230 
231  auto getEntity(const std::string & name) -> entity::EntityBase &;
232 
233  auto getEntity(const std::string & name) const -> const entity::EntityBase &;
234 
235  auto getEntityPointer(const std::string & name) const -> std::shared_ptr<entity::EntityBase>;
236 
237  // entities - respawn, despawn, reset
238  auto resetBehaviorPlugin(const std::string & name, const std::string & behavior_plugin_name)
239  -> void;
240 
241  auto respawn(
242  const std::string & name, const geometry_msgs::msg::PoseWithCovarianceStamped & new_pose,
243  const geometry_msgs::msg::PoseStamped & goal_pose) -> void;
244 
245  auto despawn(const std::string & name) -> bool;
246 
247  auto despawnEntities() -> bool;
248 
249  // entities - features
250  auto checkCollision(
251  const std::string & first_entity_name, const std::string & second_entity_name) const -> bool;
252 
253  // traffics, lanelet
254  auto getHdmapUtils() const -> const std::shared_ptr<hdmap_utils::HdMapUtils> &;
255 
256  auto getV2ITrafficLights() const -> std::shared_ptr<V2ITrafficLights>;
257 
258  auto getConventionalTrafficLights() const -> std::shared_ptr<ConventionalTrafficLights>;
277  auto addTrafficSource(
278  const double radius, const double rate, const double speed,
279  const geometry_msgs::msg::Pose & position,
280  const traffic::TrafficSource::Distribution & distribution,
281  const bool allow_spawn_outside_lane = false, const bool require_footprint_fitting = false,
282  const bool random_orientation = false, std::optional<int> random_seed = std::nullopt) -> void;
283 
284 private:
285  auto updateTimeInSim() -> bool;
286 
287  auto updateEntitiesStatusInSim() -> bool;
288 
289  auto updateTrafficLightsInSim() -> bool;
290 
291  const Configuration configuration_;
292 
293  const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters_;
294 
295  const rclcpp::Publisher<rosgraph_msgs::msg::Clock>::SharedPtr clock_pub_;
296 
297  const rclcpp::Publisher<visualization_msgs::msg::MarkerArray>::SharedPtr debug_marker_pub_;
298 
299  SimulationClock clock_;
300 
301  zeromq::MultiClient zeromq_client_;
302 
303  const std::shared_ptr<entity::EntityManager> entity_manager_ptr_;
304 
305  const std::shared_ptr<traffic::TrafficController> traffic_controller_ptr_;
306 
307  const std::shared_ptr<TrafficLights> traffic_lights_ptr_;
308 
309  const rclcpp::Subscription<std_msgs::msg::Float64>::SharedPtr real_time_factor_subscriber_;
310 };
311 } // namespace traffic_simulator
312 
313 #endif // TRAFFIC_SIMULATOR__API__API_HPP_
Definition: api.hpp:56
auto isNpcLogicStarted() const -> bool
Definition: api.cpp:65
auto addTrafficSource(const double radius, const double rate, const double speed, const geometry_msgs::msg::Pose &position, const traffic::TrafficSource::Distribution &distribution, const bool allow_spawn_outside_lane=false, const bool require_footprint_fitting=false, const bool random_orientation=false, std::optional< int > random_seed=std::nullopt) -> void
Add a traffic source to the simulation.
Definition: api.cpp:378
auto checkCollision(const std::string &first_entity_name, const std::string &second_entity_name) const -> bool
Definition: api.cpp:346
API(NodeT &&node, const Configuration &configuration, Ts &&... xs)
Definition: api.hpp:59
auto setSimulationStepTime(const double step_time) -> bool
Definition: api.cpp:39
auto attachOccupancyGridSensor(const simulation_api_schema::OccupancyGridSensorConfiguration &) -> bool
Definition: api.cpp:216
auto getEntity(const std::string &name) -> entity::EntityBase &
Definition: api.cpp:257
auto closeZMQConnection() -> void
Definition: api.cpp:69
auto getCurrentTime() const noexcept -> double
Definition: api.cpp:67
auto attachPseudoTrafficLightDetector(const simulation_api_schema::PseudoTrafficLightDetectorConfiguration &) -> bool
Definition: api.cpp:163
auto isAnyEgoSpawned() const -> bool
Definition: api.cpp:229
auto setVerbose(const bool verbose) -> void
Definition: api.cpp:37
auto getFirstEgoName() const -> std::optional< std::string >
Definition: api.cpp:231
auto getEntityNames() const -> std::vector< std::string >
Definition: api.cpp:252
auto getEntityPointer(const std::string &name) const -> std::shared_ptr< entity::EntityBase >
Definition: api.cpp:267
auto resetBehaviorPlugin(const std::string &name, const std::string &behavior_plugin_name) -> void
Definition: api.cpp:273
auto getV2ITrafficLights() const -> std::shared_ptr< V2ITrafficLights >
Definition: api.cpp:368
auto getROS2Parameter(Ts &&... xs) const -> decltype(auto)
Definition: api.hpp:98
auto init() -> bool
Definition: api.cpp:21
auto getHdmapUtils() const -> const std::shared_ptr< hdmap_utils::HdMapUtils > &
Definition: api.cpp:363
auto startNpcLogic() -> void
Definition: api.cpp:55
auto attachLidarSensor(const simulation_api_schema::LidarConfiguration &) -> bool
Definition: api.cpp:171
auto spawn(const std::string &name, const PoseType &pose, const ParamsType &parameters, const std::string &behavior="", const std::string &model3d="") -> entity::EntityBase &
Definition: api.hpp:127
auto attachDetectionSensor(const simulation_api_schema::DetectionSensorConfiguration &) -> bool
Definition: api.cpp:193
auto respawn(const std::string &name, const geometry_msgs::msg::PoseWithCovarianceStamped &new_pose, const geometry_msgs::msg::PoseStamped &goal_pose) -> void
Definition: api.cpp:279
auto getConventionalTrafficLights() const -> std::shared_ptr< ConventionalTrafficLights >
Definition: api.cpp:373
auto getEgoEntity(const std::string &name) -> entity::EgoEntity &
Definition: api.cpp:236
auto updateFrame() -> bool
Definition: api.cpp:127
auto despawnEntities() -> bool
Definition: api.cpp:338
auto attachImuSensor(const std::string &, const simulation_api_schema::ImuSensorConfiguration &configuration) -> bool
Definition: api.cpp:155
auto despawn(const std::string &name) -> bool
Definition: api.cpp:324
auto isEntityExist(const std::string &name) const -> bool
Definition: api.cpp:247
Definition: traffic_lights.hpp:33
Definition: simulation_clock.hpp:24
Definition: traffic_lights.hpp:132
Definition: traffic_lights.hpp:62
Definition: ego_entity.hpp:35
Definition: entity_base.hpp:52
Definition: misc_object_entity.hpp:27
Definition: pedestrian_entity.hpp:34
Definition: vehicle_entity.hpp:37
auto call(const simulation_api_schema::SimulationRequest &) -> simulation_api_schema::SimulationResponse
Definition: zmq_multi_client.cpp:43
#define THROW_SEMANTIC_ERROR(...)
Definition: exception.hpp:59
Definition: concatenate.hpp:24
Definition: cache.hpp:28
Definition: constants.hpp:21
void toProto(const geometry_msgs::msg::Point &p, geometry_msgs::Point &proto)
Definition: conversions.cpp:22
const TransportProtocol protocol
Definition: constants.hpp:30
Definition: lanelet_wrapper.hpp:40
LidarType
Definition: helper.hpp:141
geometry_msgs::msg::Pose Pose
Definition: lanelet_map.hpp:30
geometry_msgs::msg::PoseStamped PoseStamped
Definition: lanelet_wrapper.hpp:67
Definition: api.hpp:32
Definition: junit5.hpp:25
std::string string
Definition: junit5.hpp:26
Definition: conversions.hpp:56
A problem occurred that interfered with the continuation of the simulation.
Definition: exception.hpp:47
Definition: configuration.hpp:31
bool verbose
Definition: configuration.hpp:36
const bool standalone_mode
Definition: configuration.hpp:40
static auto noBehavior() noexcept -> const std::string &
Definition: api.hpp:48
static auto autoware() noexcept -> const std::string &
Definition: api.hpp:35
static auto defaultBehavior() noexcept -> const std::string &
Definition: pedestrian_entity.hpp:56
static auto defaultBehavior() -> const std::string &
Definition: vehicle_entity.hpp:59
class definition for the traffic controller