|
31 | 31 | #include <VtdToolkit/RDBHandler.hh>
|
32 | 32 | #endif
|
33 | 33 |
|
34 |
| -#include <cloe/core.hpp> // for Json |
| 34 | +#include <cloe/component/object.hpp> // for Object |
| 35 | +#include <cloe/core.hpp> // for Json |
35 | 36 |
|
36 | 37 | #include "omni_sensor_component.hpp" // for VtdOmniSensor
|
37 | 38 | #include "rdb_codec.hpp" // for RdbCodec
|
@@ -77,6 +78,97 @@ struct DriverControl {
|
77 | 78 | }
|
78 | 79 | };
|
79 | 80 |
|
| 81 | +struct DynObjectState { |
| 82 | + /// Object id. |
| 83 | + uint32_t base_id{0}; |
| 84 | + |
| 85 | + /// Object category (player, sensor, ...). |
| 86 | + uint8_t base_category{RDB_OBJECT_CATEGORY_PLAYER}; |
| 87 | + |
| 88 | + /// Object type (car, truck, ...). |
| 89 | + uint8_t base_type{RDB_OBJECT_TYPE_NONE}; |
| 90 | + |
| 91 | + /// Visibility mask (e.g. visible for traffic and visible for data recorder). |
| 92 | + uint16_t base_vis_mask{RDB_OBJECT_VIS_FLAG_TRAFFIC | RDB_OBJECT_VIS_FLAG_RECORDER}; |
| 93 | + |
| 94 | + /// Player name. |
| 95 | + std::string base_name; |
| 96 | + |
| 97 | + /// Object dimension and offset to cog. |
| 98 | + RDB_GEOMETRY_t base_geo; |
| 99 | + |
| 100 | + /// Object position and orientation. |
| 101 | + RDB_COORD_t base_pos; |
| 102 | + |
| 103 | + /// Object velocity and angular velocity. |
| 104 | + RDB_COORD_t ext_speed; |
| 105 | + |
| 106 | + /// Object acceleration and angular acceleration. |
| 107 | + RDB_COORD_t ext_accel; |
| 108 | + |
| 109 | + friend void to_json(cloe::Json& j, const DynObjectState& os) { |
| 110 | + j = cloe::Json{ |
| 111 | + {"base_id", os.base_id}, {"base_category", os.base_category}, |
| 112 | + {"base_type", os.base_type}, {"base_vis_mask", os.base_vis_mask}, |
| 113 | + {"base_name", os.base_name}, |
| 114 | + }; |
| 115 | + } |
| 116 | +}; |
| 117 | + |
| 118 | +/** |
| 119 | + * Map to convert from Cloe to VTD object classification. |
| 120 | + */ |
| 121 | +const std::map<cloe::Object::Class, uint8_t> cloe_vtd_obj_class_map = { |
| 122 | + {cloe::Object::Class::Car, RDB_OBJECT_TYPE_PLAYER_CAR}, |
| 123 | + {cloe::Object::Class::Truck, RDB_OBJECT_TYPE_PLAYER_TRUCK}, |
| 124 | + {cloe::Object::Class::Motorbike, RDB_OBJECT_TYPE_PLAYER_MOTORBIKE}, |
| 125 | + {cloe::Object::Class::Trailer, RDB_OBJECT_TYPE_PLAYER_TRAILER}, |
| 126 | +}; |
| 127 | + |
| 128 | +/** |
| 129 | + * Convert object geometry VTD geometry. |
| 130 | + */ |
| 131 | +RDB_GEOMETRY_t rdb_geometry_from_object(const cloe::Object& obj) { |
| 132 | + RDB_GEOMETRY_t geo; |
| 133 | + geo.dimX = obj.dimensions.x(); |
| 134 | + geo.dimY = obj.dimensions.y(); |
| 135 | + geo.dimZ = obj.dimensions.z(); |
| 136 | + geo.offX = obj.cog_offset.x(); |
| 137 | + geo.offY = obj.cog_offset.y(); |
| 138 | + geo.offZ = obj.cog_offset.z(); |
| 139 | + return geo; |
| 140 | +} |
| 141 | + |
| 142 | +RDB_COORD_t rdb_coord_from_vector3d(const Eigen::Vector3d& position, |
| 143 | + const Eigen::Vector3d& angle_rph) { |
| 144 | + RDB_COORD_t coord; |
| 145 | + coord.x = position.x(); |
| 146 | + coord.y = position.y(); |
| 147 | + coord.z = position.z(); |
| 148 | + coord.r = angle_rph.x(); |
| 149 | + coord.p = angle_rph.y(); |
| 150 | + coord.h = angle_rph.z(); |
| 151 | + coord.flags = RDB_COORD_FLAG_POINT_VALID | RDB_COORD_FLAG_ANGLES_VALID; |
| 152 | + coord.type = RDB_COORD_TYPE_INERTIAL; |
| 153 | + return coord; |
| 154 | +} |
| 155 | + |
| 156 | +RDB_COORD_t rdb_coord_from_object(const cloe::Object& obj) { |
| 157 | + Eigen::Vector3d hpr = obj.pose.rotation().matrix().eulerAngles(2, 1, 0); |
| 158 | + return rdb_coord_from_vector3d(obj.pose.translation(), |
| 159 | + Eigen::Vector3d(hpr.z(), hpr.y(), hpr.x())); |
| 160 | +} |
| 161 | + |
| 162 | +RDB_COORD_t rdb_coord_pos_from_vector3d(const Eigen::Vector3d& position) { |
| 163 | + RDB_COORD_t coord; |
| 164 | + coord.x = position.x(); |
| 165 | + coord.y = position.y(); |
| 166 | + coord.z = position.z(); |
| 167 | + coord.flags = RDB_COORD_FLAG_POINT_VALID; |
| 168 | + coord.type = RDB_COORD_TYPE_INERTIAL; |
| 169 | + return coord; |
| 170 | +} |
| 171 | + |
80 | 172 | /**
|
81 | 173 | * TaskControl contains the connection to the VTD task control server.
|
82 | 174 | *
|
@@ -172,6 +264,29 @@ class TaskControl : public VtdOmniSensor {
|
172 | 264 | driverCtrl->validityFlags = dc.validity_flags;
|
173 | 265 | }
|
174 | 266 |
|
| 267 | + void add_dyn_object_state(const DynObjectState& os) { |
| 268 | + // TODO(tobias): From the implementation of `add_driver_control`, it seems |
| 269 | + // that the actual sim time and frame no. are not needed.. |
| 270 | + handler_.addPackage(0.0, 0, RDB_PKG_ID_START_OF_FRAME); |
| 271 | + RDB_OBJECT_STATE_t* objState = reinterpret_cast<RDB_OBJECT_STATE_t*>( |
| 272 | + handler_.addPackage(0.0, 0, RDB_PKG_ID_OBJECT_STATE, /*noElements=*/1, |
| 273 | + /*extended=*/true)); |
| 274 | + if (objState == nullptr) { |
| 275 | + vtd_logger()->error("TaskControl: cannot add RDB_OBJECT_STATE package"); |
| 276 | + return; |
| 277 | + } |
| 278 | + objState->base.id = os.base_id; |
| 279 | + objState->base.category = os.base_category; |
| 280 | + objState->base.type = os.base_type; |
| 281 | + objState->base.visMask = os.base_vis_mask; |
| 282 | + std::strcpy(objState->base.name, os.base_name.c_str()); |
| 283 | + objState->base.geo = os.base_geo; |
| 284 | + objState->base.pos = os.base_pos; |
| 285 | + objState->ext.speed = os.ext_speed; |
| 286 | + objState->ext.accel = os.ext_accel; |
| 287 | + handler_.addPackage(0.0, 0, RDB_PKG_ID_END_OF_FRAME); |
| 288 | + } |
| 289 | + |
175 | 290 | /**
|
176 | 291 | * Add the trigger package, which specifies how much VTD should step.
|
177 | 292 | */
|
|
0 commit comments