$darkmode
esmini_osi_sensor.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  */
23 #pragma once
24 
25 #include <memory> // for shared_ptr<>, unique_ptr<>
26 #include <string> // for string, to_string
27 
28 #include <Eigen/Geometry> // for Isometry3d, Vector3d
29 
30 #include <esminiLib.hpp> // for SE_UpdateOSIGroundTruth, ..
31 
32 #include <cloe/component/object.hpp> // for Object
33 #include <cloe/utility/osi_message_handler.hpp> // for OsiMsgHandler
34 #include <cloe/utility/osi_transceiver.hpp> // for OsiTransceiver
35 
36 #include "esmini_logger.hpp"
37 #include "esmini_world_data.hpp" // for ESMiniEnvData
38 
39 namespace cloe_esmini {
40 
41 class ESMiniOsiReceiver : public cloe::utility::OsiTransceiver {
42  public:
43  ~ESMiniOsiReceiver() override = default;
44 
50  bool has_ground_truth() const override {
51  int ierr = 0;
52  if (update_static_ground_truth_) {
53  ierr += SE_UpdateOSIStaticGroundTruth();
54  update_static_ground_truth_ = false;
55  }
56  // Do not add the driver model's ghost vehicle to the object list.
57  ierr += SE_UpdateOSIDynamicGroundTruth(/*reportGhost=*/false);
58  return ierr == 0;
59  }
60 
64  bool has_sensor_view() const override { return false; }
65 
69  bool has_sensor_data() const override { return false; }
70 
74  void receive_osi_msgs(std::vector<std::shared_ptr<osi3::SensorView>>& /*msgs*/) override {
75  throw cloe::ModelError("ESMiniOsiReceiver: SensorView is currently not supported.");
76  }
77 
81  void receive_osi_msgs(std::vector<std::shared_ptr<osi3::SensorData>>& msgs) override {
82  if (!msgs.empty()) {
83  esmini_logger()->warn(
84  "ESMiniOsiReceiver: Non-zero length of message vector before retrieval: {}", msgs.size());
85  }
86  if (this->has_sensor_data()) {
87  const auto* sd = reinterpret_cast<const osi3::SensorData*>(SE_GetOSISensorDataRaw());
88  if (!sd->has_timestamp()) {
89  throw cloe::ModelError("ESMiniOsiSensor: No timestamp in SensorData.");
90  }
91  msgs.push_back(std::make_shared<osi3::SensorData>(*sd));
92  }
93  }
94 
98  void receive_osi_msgs(std::vector<std::shared_ptr<osi3::GroundTruth>>& msgs) override {
99  if (!msgs.empty()) {
100  esmini_logger()->warn(
101  "ESMiniOsiReceiver: Non-zero length of message vector before retrieval: {}", msgs.size());
102  }
103  if (this->has_ground_truth()) {
104  // NOTE: Make a copy because we are going to change it.
105  auto gt = *reinterpret_cast<const osi3::GroundTruth*>(SE_GetOSIGroundTruthRaw());
106  if (!gt.has_timestamp()) {
107  throw cloe::ModelError("ESMiniOsiSensor: No timestamp in GroundTruth.");
108  }
109  msgs.push_back(std::make_shared<osi3::GroundTruth>(std::move(gt)));
110  }
111  }
112 
113  void clear_cache() override {
114  // In ESMini v2.20.10, the SE_ClearOSIGroundTruth() was found
115  // to vanish the gt->lane_boundary_ list (gt->lane_boundary_size()==0 after
116  // first time step or first SE_ClearOSIGroundTruth() invocation).
117  // Note that in their OSI coding example, they do not clear the cache:
118  // EnvironmentSimulator/code-examples/osi-groundtruth/osi-groundtruth.cpp
119  }
120 
121  void to_json(cloe::Json& j) const override {
122  j = cloe::Json{
123  {"has_sensor_data", has_sensor_data()},
124  };
125  }
126 
127  private:
128  mutable bool update_static_ground_truth_{true};
129 };
130 
138 class ESMiniOsiSensor : public cloe::utility::OsiMsgHandler, public ESMiniEnvData {
139  public:
140  ~ESMiniOsiSensor() override = default;
141 
142  ESMiniOsiSensor(uint64_t owner_id, double filter_dist)
143  : OsiMsgHandler(new ESMiniOsiReceiver(), owner_id), ESMiniEnvData("osi_sensor", filter_dist) {
144  ego_object_ = std::make_shared<cloe::Object>(); // NOLINT
145  }
146 
147  void step(const cloe::Sync& s) override {
148  ESMiniEnvData::clear_cache();
149  OsiMsgHandler::process_osi_msgs<osi3::GroundTruth>(s, restart_, env_data_time_);
150  if (abs(env_data_time_.count() - env_data_time_next_.count()) >= s.step_width().count() / 100) {
151  // Environment data time deviates from expected time by more than 1% of the time step.
152  throw cloe::ModelError(
153  "ESMiniOsiSensor: ESMini data at wrong timestamp. Expected: {}. Actual: {}.",
154  env_data_time_next_.count(), env_data_time_.count());
155  }
157  }
158 
159  void store_object(std::shared_ptr<cloe::Object> obj) override { world_objects_.push_back(obj); }
160 
161  void store_lane_boundary(const cloe::LaneBoundary& lb) override { lanes_[lb.id] = lb; }
162 
163  void store_ego_object(std::shared_ptr<cloe::Object> ego_obj) override { ego_object_ = ego_obj; }
164 
165  void store_sensor_meta_data(const Eigen::Vector3d& bbcenter_to_veh_origin,
166  const Eigen::Vector3d& ego_dimensions) override {
167  // Mounting position is not provided by ESMini -> nothing to do.
168  (void)bbcenter_to_veh_origin;
169  (void)ego_dimensions;
170  }
171 
176  Eigen::Isometry3d get_static_mounting_position(const Eigen::Vector3d& bbcenter_to_veh_origin,
177  const Eigen::Vector3d& ego_dimensions) override {
178  Eigen::Isometry3d mount_osi = mount_; // Identity (sensor mountin in Cloe ego vehicle origin)
179  // Correct for the difference in reference frame z-location:
180  // Cloe/VTD: ground level; OSI: rear axle center.
181  mount_osi.translation().z() =
182  mount_osi.translation().z() - (0.5 * ego_dimensions(2) + bbcenter_to_veh_origin(2));
183  return mount_osi;
184  }
185 
189  void set_mock_conf(std::shared_ptr<const cloe::utility::SensorMockConf> mock) override {
190  this->mock_ = mock;
191  }
192 
193  // As defined in `cloe/component.hpp`
194  void reset() override {
195  ESMiniEnvData::clear_cache();
196  this->set_reset_state();
197  }
198 
199  friend void to_json(cloe::Json& j, const ESMiniOsiSensor& s) {
200  to_json(j, static_cast<const ESMiniEnvData&>(s));
201  j = cloe::Json{
202  {"osi_connection", s.osi_comm_},
203  };
204  }
205 };
206 
207 } // namespace cloe_esmini
Definition: lane_boundary.hpp:36
Definition: model.hpp:62
Definition: sync.hpp:34
virtual Duration time() const =0
virtual Duration step_width() const =0
Definition: esmini_world_data.hpp:36
virtual void set_reset_state()
Definition: esmini_world_data.hpp:81
cloe::LaneBoundaries lanes_
Lane id-to-boundary-map.
Definition: esmini_world_data.hpp:141
cloe::Objects world_objects_
World objects from last processed frame.
Definition: esmini_world_data.hpp:132
Eigen::Isometry3d mount_
Sensor mounting position and orientation.
Definition: esmini_world_data.hpp:126
bool restart_
Indicates whether reset has been requested.
Definition: esmini_world_data.hpp:117
cloe::Duration env_data_time_next_
Expected simulation time for next data message.
Definition: esmini_world_data.hpp:123
cloe::Duration env_data_time_
Simulation time from last processed data message.
Definition: esmini_world_data.hpp:120
std::shared_ptr< cloe::Object > ego_object_
ego object information from last processed frame.
Definition: esmini_world_data.hpp:135
Definition: esmini_osi_sensor.hpp:41
bool has_ground_truth() const override
Definition: esmini_osi_sensor.hpp:50
bool has_sensor_view() const override
Definition: esmini_osi_sensor.hpp:64
void receive_osi_msgs(std::vector< std::shared_ptr< osi3::GroundTruth >> &msgs) override
Definition: esmini_osi_sensor.hpp:98
void receive_osi_msgs(std::vector< std::shared_ptr< osi3::SensorView >> &) override
Definition: esmini_osi_sensor.hpp:74
bool has_sensor_data() const override
Definition: esmini_osi_sensor.hpp:69
void receive_osi_msgs(std::vector< std::shared_ptr< osi3::SensorData >> &msgs) override
Definition: esmini_osi_sensor.hpp:81
Definition: esmini_osi_sensor.hpp:138
Eigen::Isometry3d get_static_mounting_position(const Eigen::Vector3d &bbcenter_to_veh_origin, const Eigen::Vector3d &ego_dimensions) override
Definition: esmini_osi_sensor.hpp:176
void set_mock_conf(std::shared_ptr< const cloe::utility::SensorMockConf > mock) override
Definition: esmini_osi_sensor.hpp:189
void reset() override
Definition: esmini_osi_sensor.hpp:194
void step(const cloe::Sync &s) override
Definition: esmini_osi_sensor.hpp:147