21#include <unordered_set>
25#include "modules/dreamview_plus/proto/data_handler.pb.h"
37 websocket_(websocket),
44 FLAGS_localization_topic,
45 [
this](
const std::shared_ptr<LocalizationEstimate>& localization) {
46 OnLocalization(localization);
50 const std::string& channel_name) {
51 std::lock_guard<std::mutex> lck(channel_updater_map_mutex_);
52 if (!obstacle_channel_updater_map_.count(channel_name)) {
53 obstacle_channel_updater_map_[channel_name] =
55 obstacle_channel_updater_map_[channel_name]->perception_obstacle_reader_ =
59 this](
const std::shared_ptr<PerceptionObstacles>& obstacles) {
60 OnObstacles(obstacles, channel_name);
63 return obstacle_channel_updater_map_[channel_name];
66 const std::string& channel_name,
67 nlohmann::json* subscribe_param) {
68 if (channel_name.empty()) {
69 AERROR <<
"Failed to subscribe channel for channel is empty";
72 if (time_interval_ms > 0) {
74 GetObstacleChannelUpdater(channel_name);
75 if (channel_updater ==
nullptr) {
76 AERROR <<
"Failed to subscribe channel: " << channel_name
77 <<
"for channel updater not registered!";
82 [channel_name,
this]() { this->
OnTimer(channel_name); },
false));
83 channel_updater->
timer_->Start();
90 if (channel_name.empty()) {
91 AERROR <<
"Failed to unsubscribe channel for channel is empty";
96 GetObstacleChannelUpdater(channel_name);
97 if (channel_updater->
timer_) {
98 channel_updater->
timer_->Stop();
108 obstacle_channel_updater_map_.clear();
118 std::string to_send =
"";
119 GetObjects(&to_send, channel_name);
120 StreamData stream_data;
121 std::string stream_data_string;
122 stream_data.set_action(
"stream");
123 stream_data.set_data_name(
"obstacle");
124 stream_data.set_channel_name(channel_name);
125 std::vector<uint8_t> byte_data(to_send.begin(), to_send.end());
126 stream_data.set_data(&(byte_data[0]), byte_data.size());
127 stream_data.set_type(
"obstacle");
128 stream_data.SerializeToString(&stream_data_string);
137void ObstacleUpdater::OnObstacles(
138 const std::shared_ptr<PerceptionObstacles>& obstacles,
139 const std::string& channel) {
144 std::lock_guard<std::mutex> lck(updater_publish_mutex_);
145 ObstacleChannelUpdater* channel_updater =
146 GetObstacleChannelUpdater(channel);
147 channel_updater->obstacles_.clear();
148 for (
auto& obstacle : obstacles->perception_obstacle()) {
149 channel_updater->obstacles_.push_back(obstacle);
154void ObstacleUpdater::OnLocalization(
155 const std::shared_ptr<LocalizationEstimate>& localization) {
159 adc_pose_ = localization->pose();
161void ObstacleUpdater::GetObjects(std::string* to_send,
162 std::string channel_name) {
164 std::lock_guard<std::mutex> lck(updater_publish_mutex_);
165 ObstacleChannelUpdater* channel_updater =
166 GetObstacleChannelUpdater(channel_name);
168 if (channel_updater->obstacles_.empty()) {
171 channel_updater->obj_map_.clear();
172 for (
const auto& obstacle : channel_updater->obstacles_) {
173 const std::string
id = std::to_string(obstacle.id());
174 if (!apollo::common::util::ContainsKey(channel_updater->obj_map_,
id)) {
175 Object& obj = channel_updater->obj_map_[id];
176 SetObstacleInfo(obstacle, &obj);
177 SetObstaclePolygon(obstacle, &obj);
178 SetObstacleType(obstacle.type(), obstacle.sub_type(), &obj);
179 SetObstacleSensorMeasurements(obstacle, &obj, channel_updater);
180 SetObstacleSource(obstacle, &obj);
185 Object& obj = channel_updater->obj_map_[id];
186 SetObstacleInfo(obstacle, &obj);
187 SetObstaclePolygon(obstacle, &obj);
188 SetObstacleSensorMeasurements(obstacle, &obj, channel_updater);
191 Object auto_driving_car;
192 SetADCPosition(&auto_driving_car);
193 channel_updater->obstacle_objects_.Clear();
194 for (
const auto& kv : channel_updater->obj_map_) {
195 *channel_updater->obstacle_objects_.add_obstacle() = kv.second;
197 channel_updater->obstacle_objects_.mutable_auto_driving_car()->CopyFrom(
199 channel_updater->obstacle_objects_.SerializeToString(to_send);
202void ObstacleUpdater::SetObstacleInfo(
const PerceptionObstacle& obstacle,
204 if (obj ==
nullptr) {
207 obj->set_id(std::to_string(obstacle.id()));
208 obj->set_position_x(obstacle.position().x());
209 obj->set_position_y(obstacle.position().y());
210 obj->set_heading(obstacle.theta());
211 obj->set_length(obstacle.length());
212 obj->set_width(obstacle.width());
213 obj->set_height(obstacle.height());
214 obj->set_speed(std::hypot(obstacle.velocity().x(), obstacle.velocity().y()));
215 obj->set_speed_heading(
216 std::atan2(obstacle.velocity().y(), obstacle.velocity().x()));
217 obj->set_timestamp_sec(obstacle.timestamp());
218 obj->set_confidence(obstacle.has_confidence() ? obstacle.confidence() : 1);
221void ObstacleUpdater::SetObstaclePolygon(
const PerceptionObstacle& obstacle,
223 if (obj ==
nullptr) {
227 std::unordered_set<std::pair<double, double>, PairHash> seen_points;
228 obj->clear_polygon_point();
229 for (
const auto& point : obstacle.polygon_point()) {
230 std::pair<double, double> xy_pair = {point.x(), point.y()};
231 if (seen_points.count(xy_pair) == 0) {
232 PolygonPoint* poly_pt = obj->add_polygon_point();
233 poly_pt->set_x(point.x());
234 poly_pt->set_y(point.y());
235 seen_points.insert(xy_pair);
240void ObstacleUpdater::SetObstacleType(
243 if (obj ==
nullptr) {
246 switch (obstacle_type) {
248 obj->set_type(Object_Type_UNKNOWN);
251 obj->set_type(Object_Type_UNKNOWN_MOVABLE);
254 obj->set_type(Object_Type_UNKNOWN_UNMOVABLE);
257 obj->set_type(Object_Type_PEDESTRIAN);
260 obj->set_type(Object_Type_BICYCLE);
263 obj->set_type(Object_Type_VEHICLE);
266 obj->set_type(Object_Type_VIRTUAL);
269 obj->set_sub_type(obstacle_subtype);
272void ObstacleUpdater::SetObstacleSource(
const PerceptionObstacle& obstacle,
274 if (obj ==
nullptr || !obstacle.has_source()) {
278 obj->set_source(obstacle_source);
279 obj->clear_v2x_info();
281 obj->mutable_v2x_info()->CopyFrom(obstacle.v2x_info());
286void ObstacleUpdater::SetObstacleSensorMeasurements(
287 const PerceptionObstacle& obstacle, Object* obj,
288 ObstacleChannelUpdater* channel_updater) {
289 if (obj ==
nullptr) {
292 for (
const auto& sensor : obstacle.measurements()) {
293 Object* obj = (*(channel_updater->obstacle_objects_
294 .mutable_sensor_measurements()))[sensor.sensor_id()]
295 .add_sensor_measurement();
296 obj->set_id(std::to_string(sensor.id()));
297 obj->set_position_x(sensor.position().x());
298 obj->set_position_y(sensor.position().y());
299 obj->set_heading(sensor.theta());
300 obj->set_length(sensor.length());
301 obj->set_width(sensor.width());
302 obj->set_height(sensor.height());
303 SetObstacleType(sensor.type(), sensor.sub_type(), obj);
306void ObstacleUpdater::SetADCPosition(Object* auto_driving_car) {
307 auto_driving_car->set_position_x(adc_pose_.
position().
x());
308 auto_driving_car->set_position_y(adc_pose_.
position().
y());
309 auto_driving_car->set_heading(adc_pose_.
heading());
Used to perform oneshot or periodic timing tasks
ObstacleUpdater(WebSocketHandler *websocket)
void PublishMessage(const std::string &channel_name="") override
Publish Message to dreamview frontend.
void OnTimer(const std::string &channel_name="")
void StartStream(const double &time_interval_ms, const std::string &channel_name="", nlohmann::json *subscribe_param=nullptr) override
Start data flow.
void StopStream(const std::string &channel_name) override
Stop data flow.
void GetChannelMsg(std::vector< std::string > *channels)
GetChannelMsg
Base Class for data updater with multiply channels.
void GetChannelMsgWithFilter(std::vector< std::string > *channels)
The WebSocketHandler, built on top of CivetWebSocketHandler, is a websocket handler that handles diff...
bool BroadcastBinaryData(const std::string &data, bool skippable=false)
Sends the provided binary data to all the connected clients.
std::unique_ptr< Node > CreateNode(const std::string &node_name, const std::string &name_space)
std::vector< PerceptionObstacle > obstacles_
Obstacles obstacle_objects_
std::unique_ptr< cyber::Timer > timer_
std::unordered_map< std::string, Object > obj_map_
optional apollo::common::PointENU position