$darkmode
task_control.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 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  */
22 #pragma once
23 
24 #include <memory> // for unique_ptr<>
25 #include <string> // for string
26 #include <utility> // for move
27 
28 #include <cloe/component/object.hpp> // for Object
29 #include <cloe/core.hpp> // for Json
30 
31 #include "vtd_version.hpp"
32 #if (VTD_API_VERSION_EPOCH == 0)
33  #include <RDBHandler.hh>
34 #else
35  #include <VtdToolkit/RDBHandler.hh>
36 #endif
37 
38 #include "omni_sensor_component.hpp" // for VtdOmniSensor
39 #include "rdb_codec.hpp" // for RdbCodec
40 #include "vtd_logger.hpp" // for vtd_logger
41 
42 namespace vtd {
43 
44 struct DriverControl {
46  uint32_t player_id{0};
47 
50 
52  float target_steering{0};
53 
60  uint32_t driver_flags{0};
61 
69  uint32_t validity_flags{0};
70 
71  friend void to_json(cloe::Json& j, const DriverControl& dc) {
72  j = cloe::Json{
73  {"player_id", dc.player_id},
74  {"target_acceleration", dc.target_acceleration},
75  {"target_steering", dc.target_steering},
76  {"driver_flags", dc.driver_flags},
77  {"validity_flags", dc.validity_flags},
78  };
79  }
80 };
81 
84  uint32_t base_id{0};
85 
87  uint8_t base_category{RDB_OBJECT_CATEGORY_PLAYER};
88 
90  uint8_t base_type{RDB_OBJECT_TYPE_NONE};
91 
93  uint16_t base_vis_mask{RDB_OBJECT_VIS_FLAG_TRAFFIC | RDB_OBJECT_VIS_FLAG_RECORDER};
94 
96  std::string base_name;
97 
99  RDB_GEOMETRY_t base_geo;
100 
102  RDB_COORD_t base_pos;
103 
105  RDB_COORD_t ext_speed;
106 
108  RDB_COORD_t ext_accel;
109 
110  friend void to_json(cloe::Json& j, const DynObjectState& os) {
111  j = cloe::Json{
112  {"base_id", os.base_id}, {"base_category", os.base_category},
113  {"base_type", os.base_type}, {"base_vis_mask", os.base_vis_mask},
114  {"base_name", os.base_name},
115  };
116  }
117 };
118 
122 const std::map<cloe::Object::Class, uint8_t> cloe_vtd_obj_class_map = {
123  {cloe::Object::Class::Car, RDB_OBJECT_TYPE_PLAYER_CAR},
124  {cloe::Object::Class::Truck, RDB_OBJECT_TYPE_PLAYER_TRUCK},
125  {cloe::Object::Class::Motorbike, RDB_OBJECT_TYPE_PLAYER_MOTORBIKE},
126  {cloe::Object::Class::Trailer, RDB_OBJECT_TYPE_PLAYER_TRAILER},
127 };
128 
132 RDB_GEOMETRY_t rdb_geometry_from_object(const cloe::Object& obj) {
133  RDB_GEOMETRY_t geo;
134  geo.dimX = obj.dimensions.x();
135  geo.dimY = obj.dimensions.y();
136  geo.dimZ = obj.dimensions.z();
137  geo.offX = obj.cog_offset.x();
138  geo.offY = obj.cog_offset.y();
139  geo.offZ = obj.cog_offset.z();
140  return geo;
141 }
142 
143 RDB_COORD_t rdb_coord_from_vector3d(const Eigen::Vector3d& position,
144  const Eigen::Vector3d& angle_rph) {
145  RDB_COORD_t coord;
146  coord.x = position.x();
147  coord.y = position.y();
148  coord.z = position.z();
149  coord.r = angle_rph.x();
150  coord.p = angle_rph.y();
151  coord.h = angle_rph.z();
152  coord.flags = RDB_COORD_FLAG_POINT_VALID | RDB_COORD_FLAG_ANGLES_VALID;
153  coord.type = RDB_COORD_TYPE_INERTIAL;
154  return coord;
155 }
156 
157 RDB_COORD_t rdb_coord_from_object(const cloe::Object& obj) {
158  Eigen::Vector3d hpr = obj.pose.rotation().matrix().eulerAngles(2, 1, 0);
159  return rdb_coord_from_vector3d(obj.pose.translation(),
160  Eigen::Vector3d(hpr.z(), hpr.y(), hpr.x()));
161 }
162 
163 RDB_COORD_t rdb_coord_pos_from_vector3d(const Eigen::Vector3d& position) {
164  RDB_COORD_t coord;
165  coord.x = position.x();
166  coord.y = position.y();
167  coord.z = position.z();
168  coord.flags = RDB_COORD_FLAG_POINT_VALID;
169  coord.type = RDB_COORD_TYPE_INERTIAL;
170  return coord;
171 }
172 
208 class TaskControl : public VtdOmniSensor {
209  public:
210  explicit TaskControl(std::unique_ptr<RdbTransceiver>&& rdb_transceiver)
211  : VtdOmniSensor(std::move(rdb_transceiver), UNDEFINED_OWNER_ID) {
212  handler_.initMsg();
213  }
214 
215  virtual ~TaskControl() = default;
216 
218  void process(RDB_DRIVER_CTRL_t* driver_ctrl) override {
219  // Steering speed at the front wheels [rad/s].
220  if (driver_ctrl->validityFlags & RDB_DRIVER_INPUT_VALIDITY_STEERING_SPEED) {
221  steering_wheel_speed_[driver_ctrl->playerId] = driver_ctrl->steeringSpeed;
222  } else {
223  vtd_logger()->warn("{}: steeringSpeed missing in RDB_DRIVER_CTRL_t", this->get_name());
224  steering_wheel_speed_[driver_ctrl->playerId] = 0.0;
225  }
226 
227  // Longitudinal acceleration request [m/s2].
228  if (driver_ctrl->validityFlags & RDB_DRIVER_INPUT_VALIDITY_TGT_ACCEL) {
229  driver_request_accel_[driver_ctrl->playerId] = driver_ctrl->accelTgt;
230  } else {
231  vtd_logger()->warn("{}: accelTgt missing in RDB_DRIVER_CTRL_t", this->get_name());
232  driver_request_accel_[driver_ctrl->playerId] = 0.0;
233  }
234  // Steering request (angle at wheels) [rad].
235  if (driver_ctrl->validityFlags & RDB_DRIVER_INPUT_VALIDITY_TGT_STEERING) {
236  driver_request_steering_angle_[driver_ctrl->playerId] = driver_ctrl->steeringTgt;
237  } else {
238  vtd_logger()->warn("{}: steeringTgt missing in RDB_DRIVER_CTRL_t", this->get_name());
239  driver_request_steering_angle_[driver_ctrl->playerId] = 0.0;
240  }
241  }
242 
243  void reset() override {
245  steering_wheel_speed_.clear();
246  driver_request_accel_.clear();
247  driver_request_steering_angle_.clear();
248  }
249 
254  RDB_DRIVER_CTRL_t* driverCtrl =
255  reinterpret_cast<RDB_DRIVER_CTRL_t*>(handler_.addPackage(0.0, 0, RDB_PKG_ID_DRIVER_CTRL));
256  if (driverCtrl == nullptr) {
257  vtd_logger()->error("TaskControl: cannot add RDB_PKG_ID_DRIVER_CTRL package");
258  return;
259  }
260 
261  driverCtrl->playerId = dc.player_id;
262  driverCtrl->accelTgt = dc.target_acceleration;
263  driverCtrl->steeringTgt = dc.target_steering;
264  driverCtrl->flags = dc.driver_flags;
265  driverCtrl->validityFlags = dc.validity_flags;
266  }
267 
268  void add_dyn_object_state(const DynObjectState& os) {
269  // TODO(tobias): From the implementation of `add_driver_control`, it seems
270  // that the actual sim time and frame no. are not needed..
271  handler_.addPackage(0.0, 0, RDB_PKG_ID_START_OF_FRAME);
272  RDB_OBJECT_STATE_t* objState = reinterpret_cast<RDB_OBJECT_STATE_t*>(
273  handler_.addPackage(0.0, 0, RDB_PKG_ID_OBJECT_STATE, /*noElements=*/1,
274  /*extended=*/true));
275  if (objState == nullptr) {
276  vtd_logger()->error("TaskControl: cannot add RDB_OBJECT_STATE package");
277  return;
278  }
279  objState->base.id = os.base_id;
280  objState->base.category = os.base_category;
281  objState->base.type = os.base_type;
282  objState->base.visMask = os.base_vis_mask;
283  std::strcpy(objState->base.name, os.base_name.c_str());
284  objState->base.geo = os.base_geo;
285  objState->base.pos = os.base_pos;
286  objState->ext.speed = os.ext_speed;
287  objState->ext.accel = os.ext_accel;
288  handler_.addPackage(0.0, 0, RDB_PKG_ID_END_OF_FRAME);
289  }
290 
294  void add_trigger(cloe::Duration delta_t) {
295  RDB_TRIGGER_t* trigger =
296  reinterpret_cast<RDB_TRIGGER_t*>(handler_.addPackage(0.0, 0, RDB_PKG_ID_TRIGGER));
297  if (trigger == nullptr) {
298  vtd_logger()->error("TaskControl: cannot add RDB_PKG_ID_DRIVER_CTRL package");
299  return;
300  }
301 
302  vtd_logger()->trace("TaskControl: setting trigger={} ns", delta_t.count());
303  trigger->deltaT = std::chrono::duration_cast<std::chrono::duration<float>>(delta_t).count();
304  trigger->frameNo = 0;
305  trigger->features = 0;
306  }
307 
311  void send_packages() {
312  rdb_->send(handler_.getMsg(), handler_.getMsgTotalSize());
313  handler_.initMsg();
314  }
315 
323  this->add_trigger(delta_t);
324  this->send_packages();
325  }
326 
330  double get_steering_wheel_speed(uint64_t id) const { return steering_wheel_speed_.at(id); }
331 
335  double get_driver_request_acceleration(uint64_t id) const { return driver_request_accel_.at(id); }
336 
341  return driver_request_accel_.find(id) != driver_request_accel_.end();
342  }
343 
347  double get_driver_request_steering_angle(uint64_t id) const {
348  return driver_request_steering_angle_.at(id);
349  }
350 
355  return driver_request_steering_angle_.find(id) != driver_request_steering_angle_.end();
356  }
357 
358  friend void to_json(cloe::Json& j, const TaskControl& tc) {
359  j = cloe::Json{{"rdb_connection", tc.rdb_}};
360  }
361 
362  protected:
364  Framework::RDBHandler handler_;
365  std::map<int, double> steering_wheel_speed_;
366  std::map<int, double> driver_request_accel_;
367  std::map<int, double> driver_request_steering_angle_;
368 };
369 
370 } // namespace vtd
std::unique_ptr< RdbTransceiver > rdb_
Definition: rdb_codec.hpp:157
Definition: task_control.hpp:208
void add_driver_control(const DriverControl &dc)
Definition: task_control.hpp:253
bool has_driver_request_acceleration(uint64_t id)
Definition: task_control.hpp:340
Framework::RDBHandler handler_
RDBHandler helps us conveniently construct RDB messages.
Definition: task_control.hpp:364
void reset() override
Definition: task_control.hpp:243
void send_packages()
Definition: task_control.hpp:311
void add_trigger_and_send(cloe::Duration delta_t)
Definition: task_control.hpp:322
bool has_driver_request_steering_angle(uint64_t id)
Definition: task_control.hpp:354
double get_driver_request_steering_angle(uint64_t id) const
Definition: task_control.hpp:347
double get_steering_wheel_speed(uint64_t id) const
Definition: task_control.hpp:330
double get_driver_request_acceleration(uint64_t id) const
Definition: task_control.hpp:335
void add_trigger(cloe::Duration delta_t)
Definition: task_control.hpp:294
Definition: omni_sensor_component.hpp:73
void reset() override
Definition: omni_sensor_component.hpp:164
virtual void process(RDB_MSG_t *msg, bool &restart, cloe::Duration &sim_time)
Definition: rdb_codec.cpp:249
const std::string & get_name() const override
Definition: omni_sensor_component.hpp:161
std::chrono::nanoseconds Duration
Definition: cloe_fwd.hpp:36
Definition: object.hpp:51
Eigen::Vector3d dimensions
Dimensions in [m].
Definition: object.hpp:72
Eigen::Vector3d cog_offset
Center of geometry offset in [m].
Definition: object.hpp:75
Eigen::Isometry3d pose
Pose in [m] and [rad].
Definition: object.hpp:69
Definition: task_control.hpp:44
float target_steering
Target steering angle in [rad].
Definition: task_control.hpp:52
float target_acceleration
Target acceleration in [m/s^2].
Definition: task_control.hpp:49
uint32_t validity_flags
Definition: task_control.hpp:69
uint32_t driver_flags
Definition: task_control.hpp:60
uint32_t player_id
VTD player ID.
Definition: task_control.hpp:46
Definition: task_control.hpp:82
uint8_t base_category
Object category (player, sensor, ...).
Definition: task_control.hpp:87
RDB_COORD_t ext_speed
Object velocity and angular velocity.
Definition: task_control.hpp:105
uint16_t base_vis_mask
Visibility mask (e.g. visible for traffic and visible for data recorder).
Definition: task_control.hpp:93
RDB_COORD_t ext_accel
Object acceleration and angular acceleration.
Definition: task_control.hpp:108
RDB_GEOMETRY_t base_geo
Object dimension and offset to cog.
Definition: task_control.hpp:99
uint8_t base_type
Object type (car, truck, ...).
Definition: task_control.hpp:90
RDB_COORD_t base_pos
Object position and orientation.
Definition: task_control.hpp:102
std::string base_name
Player name.
Definition: task_control.hpp:96
uint32_t base_id
Object id.
Definition: task_control.hpp:84
const std::map< cloe::Object::Class, uint8_t > cloe_vtd_obj_class_map
Definition: task_control.hpp:122
RDB_GEOMETRY_t rdb_geometry_from_object(const cloe::Object &obj)
Definition: task_control.hpp:132