21#include <unordered_set>
25#include "modules/dreamview_plus/proto/data_handler.pb.h"
36 : websocket_(websocket), node_(cyber::CreateNode(
"obstacle_updater")) {
42 FLAGS_localization_topic,
43 [
this](
const std::shared_ptr<LocalizationEstimate>& localization) {
44 OnLocalization(localization);
48 const std::string& channel_name) {
49 std::lock_guard<std::mutex> lck(channel_updater_map_mutex_);
50 if (!obstacle_channel_updater_map_.count(channel_name)) {
51 obstacle_channel_updater_map_[channel_name] =
53 obstacle_channel_updater_map_[channel_name]->perception_obstacle_reader_ =
57 this](
const std::shared_ptr<PerceptionObstacles>& obstacles) {
58 OnObstacles(obstacles, channel_name);
61 return obstacle_channel_updater_map_[channel_name];
64 const std::string& channel_name,
65 nlohmann::json* subscribe_param) {
66 if (channel_name.empty()) {
67 AERROR <<
"Failed to subscribe channel for channel is empty";
70 if (time_interval_ms > 0) {
72 GetObstacleChannelUpdater(channel_name);
73 if (channel_updater ==
nullptr) {
74 AERROR <<
"Failed to subscribe channel: " << channel_name
75 <<
"for channel updater not registered!";
80 [channel_name,
this]() { this->
OnTimer(channel_name); },
false));
81 channel_updater->
timer_->Start();
88 if (channel_name.empty()) {
89 AERROR <<
"Failed to unsubscribe channel for channel is empty";
94 GetObstacleChannelUpdater(channel_name);
95 if (channel_updater->
timer_) {
96 channel_updater->
timer_->Stop();
106 obstacle_channel_updater_map_.clear();
116 std::string to_send =
"";
117 GetObjects(&to_send, channel_name);
118 StreamData stream_data;
119 std::string stream_data_string;
120 stream_data.set_action(
"stream");
121 stream_data.set_data_name(
"obstacle");
122 stream_data.set_channel_name(channel_name);
123 std::vector<uint8_t> byte_data(to_send.begin(), to_send.end());
124 stream_data.set_data(&(byte_data[0]), byte_data.size());
125 stream_data.set_type(
"obstacle");
126 stream_data.SerializeToString(&stream_data_string);
135void ObstacleUpdater::OnObstacles(
136 const std::shared_ptr<PerceptionObstacles>& obstacles,
137 const std::string& channel) {
142 std::lock_guard<std::mutex> lck(updater_publish_mutex_);
143 ObstacleChannelUpdater* channel_updater =
144 GetObstacleChannelUpdater(channel);
145 channel_updater->obstacles_.clear();
146 for (
auto& obstacle : obstacles->perception_obstacle()) {
147 channel_updater->obstacles_.push_back(obstacle);
152void ObstacleUpdater::OnLocalization(
153 const std::shared_ptr<LocalizationEstimate>& localization) {
157 adc_pose_ = localization->pose();
159void ObstacleUpdater::GetObjects(std::string* to_send,
160 std::string channel_name) {
162 std::lock_guard<std::mutex> lck(updater_publish_mutex_);
163 ObstacleChannelUpdater* channel_updater =
164 GetObstacleChannelUpdater(channel_name);
166 if (channel_updater->obstacles_.empty()) {
169 channel_updater->obj_map_.clear();
170 for (
const auto& obstacle : channel_updater->obstacles_) {
171 const std::string
id = std::to_string(obstacle.id());
172 if (!apollo::common::util::ContainsKey(channel_updater->obj_map_,
id)) {
173 Object& obj = channel_updater->obj_map_[id];
174 SetObstacleInfo(obstacle, &obj);
175 SetObstaclePolygon(obstacle, &obj);
176 SetObstacleType(obstacle.type(), obstacle.sub_type(), &obj);
177 SetObstacleSensorMeasurements(obstacle, &obj, channel_updater);
178 SetObstacleSource(obstacle, &obj);
183 Object& obj = channel_updater->obj_map_[id];
184 SetObstacleInfo(obstacle, &obj);
185 SetObstaclePolygon(obstacle, &obj);
186 SetObstacleSensorMeasurements(obstacle, &obj, channel_updater);
189 Object auto_driving_car;
190 SetADCPosition(&auto_driving_car);
191 channel_updater->obstacle_objects_.Clear();
192 for (
const auto& kv : channel_updater->obj_map_) {
193 *channel_updater->obstacle_objects_.add_obstacle() = kv.second;
195 channel_updater->obstacle_objects_.mutable_auto_driving_car()->CopyFrom(
197 channel_updater->obstacle_objects_.SerializeToString(to_send);
200void ObstacleUpdater::SetObstacleInfo(
const PerceptionObstacle& obstacle,
202 if (obj ==
nullptr) {
205 obj->set_id(std::to_string(obstacle.id()));
206 obj->set_position_x(obstacle.position().x());
207 obj->set_position_y(obstacle.position().y());
208 obj->set_heading(obstacle.theta());
209 obj->set_length(obstacle.length());
210 obj->set_width(obstacle.width());
211 obj->set_height(obstacle.height());
212 obj->set_speed(std::hypot(obstacle.velocity().x(), obstacle.velocity().y()));
213 obj->set_speed_heading(
214 std::atan2(obstacle.velocity().y(), obstacle.velocity().x()));
215 obj->set_timestamp_sec(obstacle.timestamp());
216 obj->set_confidence(obstacle.has_confidence() ? obstacle.confidence() : 1);
219void ObstacleUpdater::SetObstaclePolygon(
const PerceptionObstacle& obstacle,
221 if (obj ==
nullptr) {
225 std::unordered_set<std::pair<double, double>, PairHash> seen_points;
226 obj->clear_polygon_point();
227 for (
const auto& point : obstacle.polygon_point()) {
228 std::pair<double, double> xy_pair = {point.x(), point.y()};
229 if (seen_points.count(xy_pair) == 0) {
230 PolygonPoint* poly_pt = obj->add_polygon_point();
231 poly_pt->set_x(point.x());
232 poly_pt->set_y(point.y());
233 seen_points.insert(xy_pair);
238void ObstacleUpdater::SetObstacleType(
241 if (obj ==
nullptr) {
244 switch (obstacle_type) {
246 obj->set_type(Object_Type_UNKNOWN);
249 obj->set_type(Object_Type_UNKNOWN_MOVABLE);
252 obj->set_type(Object_Type_UNKNOWN_UNMOVABLE);
255 obj->set_type(Object_Type_PEDESTRIAN);
258 obj->set_type(Object_Type_BICYCLE);
261 obj->set_type(Object_Type_VEHICLE);
264 obj->set_type(Object_Type_VIRTUAL);
267 obj->set_sub_type(obstacle_subtype);
270void ObstacleUpdater::SetObstacleSource(
const PerceptionObstacle& obstacle,
272 if (obj ==
nullptr || !obstacle.has_source()) {
276 obj->set_source(obstacle_source);
277 obj->clear_v2x_info();
279 obj->mutable_v2x_info()->CopyFrom(obstacle.v2x_info());
284void ObstacleUpdater::SetObstacleSensorMeasurements(
285 const PerceptionObstacle& obstacle, Object* obj,
286 ObstacleChannelUpdater* channel_updater) {
287 if (obj ==
nullptr) {
290 for (
const auto& sensor : obstacle.measurements()) {
291 Object* obj = (*(channel_updater->obstacle_objects_
292 .mutable_sensor_measurements()))[sensor.sensor_id()]
293 .add_sensor_measurement();
294 obj->set_id(std::to_string(sensor.id()));
295 obj->set_position_x(sensor.position().x());
296 obj->set_position_y(sensor.position().y());
297 obj->set_heading(sensor.theta());
298 obj->set_length(sensor.length());
299 obj->set_width(sensor.width());
300 obj->set_height(sensor.height());
301 SetObstacleType(sensor.type(), sensor.sub_type(), obj);
304void ObstacleUpdater::SetADCPosition(Object* auto_driving_car) {
305 auto_driving_car->set_position_x(adc_pose_.
position().
x());
306 auto_driving_car->set_position_y(adc_pose_.
position().
y());
307 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
void GetChannelMsgWithFilter(std::vector< std::string > *channels, const std::string &filter_message_type, const std::string &filter_channel, bool reverse_filter_channel=false)
GetChannelMsgWithFilter:by msg type and channel filter field to filter channels for DataUpdater
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::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