$darkmode
esmini_vehicle.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2023 Robert Bosch GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * SPDX-License-Identifier: Apache-2.0
17  */
28 #include <float.h> // for DBL_MAX
29 
30 #include <cloe/component/lane_boundary.hpp> // for LaneBoundary
31 #include <cloe/component/lane_sensor_functional.hpp> // for LaneSensorFilter
32 #include <cloe/component/object_sensor_functional.hpp> // for ObjectSensorFilter
33 #include "esmini_ego_control.hpp" // for ESMiniEgoControl
34 #include "esmini_osi_sensor.hpp" // for ESMiniOsiSensor
35 #include "esmini_sensor_components.hpp" // for ESMiniEgoSensor, ESMiniObjectSensor, ..
36 #include "esmini_world_data.hpp" // for ESMiniEnvData
37 
38 namespace cloe_esmini {
39 
40 class ESMiniVehicle : public cloe::Vehicle {
41  public:
50  ESMiniVehicle(uint64_t id, const std::string& name, const ESMiniVehicleConfig& config)
51  : Vehicle(id, name) {
52  auto osi_gnd_truth = std::make_shared<ESMiniOsiSensor>(id, config.filter_dist);
53  env_data_ = osi_gnd_truth;
54  osi_gnd_truth->set_name(name + "_osi_sensor");
55 
56  // Add ego sensor
57  this->new_component(new ESMiniEgoSensor{id, osi_gnd_truth},
58  cloe::CloeComponent::GROUNDTRUTH_EGO_SENSOR,
59  cloe::CloeComponent::DEFAULT_EGO_SENSOR);
60 
61  // Add object sensor
62  this->new_component(new ESMiniObjectSensor{osi_gnd_truth},
63  cloe::CloeComponent::GROUNDTRUTH_WORLD_SENSOR,
64  cloe::CloeComponent::DEFAULT_WORLD_SENSOR);
65 
66  // Only keep object data within configured filter distance.
67  auto filter_fct_obj = [fdist = config.filter_dist](const cloe::Object& obj) {
68  // Object position is stored in sensor coordinate system.
69  return obj.pose.translation().norm() < fdist;
70  };
71  this->emplace_component(
72  std::make_shared<cloe::ObjectSensorFilter>(
73  this->get<cloe::ObjectSensor>(cloe::CloeComponent::DEFAULT_WORLD_SENSOR),
74  filter_fct_obj),
75  cloe::CloeComponent::DEFAULT_WORLD_SENSOR);
76 
77  // Add lane-boundary sensor
78  this->new_component(new ESMiniLaneBoundarySensor{osi_gnd_truth},
79  cloe::CloeComponent::GROUNDTRUTH_LANE_SENSOR,
80  cloe::CloeComponent::DEFAULT_LANE_SENSOR);
81 
82  // Only keep lane boundary data within configured filter distance.
83  auto filter_fct_lbs = [fdist = config.filter_dist](const cloe::LaneBoundary& lb) {
84  double min_dist = DBL_MAX;
85  for (uint64_t i = 1; i < lb.points.size(); ++i) {
86  const auto& pt0 = lb.points[i - 1];
87  const auto& pt1 = lb.points[i];
88  Eigen::Vector3d dpt = pt1 - pt0;
89  // Compute minimum distance of the line through two neighboring points and the sensor frame origin.
90  // See https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Vector_formulation.
91  double dpt_abs = dpt.norm();
92  if (dpt_abs > 0.1) {
93  // Unit directional vector.
94  dpt /= dpt_abs;
95  // Compute point with minimum distance to origin (=sensor mounting position).
96  Eigen::Vector3d ptm = pt0 - (pt0.dot(dpt)) * dpt;
97  // Only use that point if it is located between pt0 and pt1.
98  double s;
99  if (dpt.x() > dpt.y()) {
100  s = (ptm.x() - pt0.x()) / dpt.x();
101  } else {
102  s = (ptm.y() - pt0.y()) / dpt.y();
103  }
104  if (s <= 0) {
105  min_dist = std::min(min_dist, pt0.norm());
106  } else if (s >= dpt_abs) {
107  min_dist = std::min(min_dist, pt1.norm());
108  } else {
109  min_dist = std::min(min_dist, ptm.norm());
110  }
111  } else {
112  // Negligible distance between neighboring points.
113  min_dist = std::min(min_dist, pt0.norm());
114  }
115  }
116  return min_dist < fdist;
117  };
118 
119  this->emplace_component(
120  std::make_shared<cloe::LaneBoundarySensorFilter>(
121  this->get<cloe::LaneBoundarySensor>(cloe::CloeComponent::DEFAULT_LANE_SENSOR),
122  filter_fct_lbs),
123  cloe::CloeComponent::DEFAULT_LANE_SENSOR);
124 
125  // TODO(tobias): Add groundtruth world sensor and emplace it by a static object only version
126 
127  if (config.is_closed_loop) {
128  // Add actuator component to receive target acceleration and steering angle from controller.
129  ego_control_ = std::make_shared<ESMiniEgoControl>(id);
130  this->add_component(ego_control_,
131  cloe::CloeComponent::GROUNDTRUTH_LATLONG_ACTUATOR,
132  cloe::CloeComponent::DEFAULT_LATLONG_ACTUATOR);
133  }
134  }
135 
142  if (ego_control_) {
143  this->ego_control_->step(s);
144  }
145  }
146 
151  env_data_->step(s);
152  return env_data_->time();
153  }
154 
158  cloe::Duration process(const cloe::Sync& sync) final { return Vehicle::process(sync); }
159 
160  private:
162  std::shared_ptr<ESMiniEnvData> env_data_;
164  std::shared_ptr<ESMiniEgoControl> ego_control_{nullptr};
165 };
166 
167 } // namespace esmini
const std::string & name() const
Definition: entity.hpp:67
Definition: lane_boundary.hpp:36
Definition: sync.hpp:34
Definition: vehicle.hpp:106
Definition: esmini_sensor_components.hpp:30
Definition: esmini_sensor_components.hpp:62
Definition: esmini_sensor_components.hpp:48
Definition: esmini_vehicle.hpp:40
void esmini_step_ego_position(const cloe::Sync &s)
Definition: esmini_vehicle.hpp:141
cloe::Duration process(const cloe::Sync &sync) final
Definition: esmini_vehicle.hpp:158
ESMiniVehicle(uint64_t id, const std::string &name, const ESMiniVehicleConfig &config)
Definition: esmini_vehicle.hpp:50
cloe::Duration esmini_get_environment_data(const cloe::Sync &s)
Definition: esmini_vehicle.hpp:150
std::chrono::nanoseconds Duration
Definition: cloe_fwd.hpp:36
Definition: object.hpp:51
Definition: esmini_conf.hpp:37
double filter_dist
Only keep ground truth data within given distance.
Definition: esmini_conf.hpp:42
bool is_closed_loop
Externally controlled esmini vehicle.
Definition: esmini_conf.hpp:39