Apollo 11.0
自动驾驶开放平台
obstacle_updater.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2023 The Apollo Authors. All Rights Reserved.
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
18
19#include <memory>
20#include <string>
21#include <unordered_set>
22#include <utility>
23#include <vector>
24
25#include "modules/dreamview_plus/proto/data_handler.pb.h"
26
29namespace apollo {
30namespace dreamview {
31
36 : websocket_(websocket), node_(cyber::CreateNode("obstacle_updater")) {
37 Init();
38}
39
41 localization_reader_ = node_->CreateReader<LocalizationEstimate>(
42 FLAGS_localization_topic,
43 [this](const std::shared_ptr<LocalizationEstimate>& localization) {
44 OnLocalization(localization);
45 });
46}
47ObstacleChannelUpdater* ObstacleUpdater::GetObstacleChannelUpdater(
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] =
52 new ObstacleChannelUpdater(channel_name);
53 obstacle_channel_updater_map_[channel_name]->perception_obstacle_reader_ =
54 node_->CreateReader<PerceptionObstacles>(
55 channel_name,
56 [channel_name,
57 this](const std::shared_ptr<PerceptionObstacles>& obstacles) {
58 OnObstacles(obstacles, channel_name);
59 });
60 }
61 return obstacle_channel_updater_map_[channel_name];
62}
63void ObstacleUpdater::StartStream(const double& time_interval_ms,
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";
68 return;
69 }
70 if (time_interval_ms > 0) {
71 ObstacleChannelUpdater* channel_updater =
72 GetObstacleChannelUpdater(channel_name);
73 if (channel_updater == nullptr) {
74 AERROR << "Failed to subscribe channel: " << channel_name
75 << "for channel updater not registered!";
76 return;
77 }
78 channel_updater->timer_.reset(new cyber::Timer(
79 time_interval_ms,
80 [channel_name, this]() { this->OnTimer(channel_name); }, false));
81 channel_updater->timer_->Start();
82 } else {
83 this->OnTimer(channel_name);
84 }
85}
86
87void ObstacleUpdater::StopStream(const std::string& channel_name) {
88 if (channel_name.empty()) {
89 AERROR << "Failed to unsubscribe channel for channel is empty";
90 return;
91 }
92 if (enabled_) {
93 ObstacleChannelUpdater* channel_updater =
94 GetObstacleChannelUpdater(channel_name);
95 if (channel_updater->timer_) {
96 channel_updater->timer_->Stop();
97 }
98 channel_updater->obj_map_.clear();
99 channel_updater->obstacle_objects_.Clear();
100 channel_updater->obstacles_.clear();
101 }
102}
103
105 if (enabled_) {
106 obstacle_channel_updater_map_.clear();
107 }
108 enabled_ = false;
109}
110
111void ObstacleUpdater::OnTimer(const std::string& channel_name) {
112 PublishMessage(channel_name);
113}
114
115void ObstacleUpdater::PublishMessage(const std::string& channel_name) {
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);
127 websocket_->BroadcastBinaryData(stream_data_string);
128}
129
130void ObstacleUpdater::GetChannelMsg(std::vector<std::string>* channels) {
131 enabled_ = true;
132 GetChannelMsgWithFilter(channels, "perception.PerceptionObstacles", "");
133}
134
135void ObstacleUpdater::OnObstacles(
136 const std::shared_ptr<PerceptionObstacles>& obstacles,
137 const std::string& channel) {
138 if (!enabled_) {
139 return;
140 }
141 {
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);
148 }
149 }
150}
151
152void ObstacleUpdater::OnLocalization(
153 const std::shared_ptr<LocalizationEstimate>& localization) {
154 if (!enabled_) {
155 return;
156 }
157 adc_pose_ = localization->pose();
158}
159void ObstacleUpdater::GetObjects(std::string* to_send,
160 std::string channel_name) {
161 {
162 std::lock_guard<std::mutex> lck(updater_publish_mutex_);
163 ObstacleChannelUpdater* channel_updater =
164 GetObstacleChannelUpdater(channel_name);
165
166 if (channel_updater->obstacles_.empty()) {
167 return;
168 }
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);
179 } else {
180 // The object is already in the map.
181 // Only the coordinates of the polygon and its own coordinates are
182 // updated.
183 Object& obj = channel_updater->obj_map_[id];
184 SetObstacleInfo(obstacle, &obj);
185 SetObstaclePolygon(obstacle, &obj);
186 SetObstacleSensorMeasurements(obstacle, &obj, channel_updater);
187 }
188 }
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;
194 }
195 channel_updater->obstacle_objects_.mutable_auto_driving_car()->CopyFrom(
196 auto_driving_car);
197 channel_updater->obstacle_objects_.SerializeToString(to_send);
198 }
199}
200void ObstacleUpdater::SetObstacleInfo(const PerceptionObstacle& obstacle,
201 Object* obj) {
202 if (obj == nullptr) {
203 return;
204 }
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);
217}
218
219void ObstacleUpdater::SetObstaclePolygon(const PerceptionObstacle& obstacle,
220 Object* obj) {
221 if (obj == nullptr) {
222 return;
223 }
224
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);
234 }
235 }
236}
237
238void ObstacleUpdater::SetObstacleType(
239 const PerceptionObstacle::Type obstacle_type,
240 const PerceptionObstacle::SubType obstacle_subtype, Object* obj) {
241 if (obj == nullptr) {
242 return;
243 }
244 switch (obstacle_type) {
246 obj->set_type(Object_Type_UNKNOWN);
247 break;
249 obj->set_type(Object_Type_UNKNOWN_MOVABLE);
250 break;
252 obj->set_type(Object_Type_UNKNOWN_UNMOVABLE);
253 break;
255 obj->set_type(Object_Type_PEDESTRIAN);
256 break;
258 obj->set_type(Object_Type_BICYCLE);
259 break;
261 obj->set_type(Object_Type_VEHICLE);
262 break;
263 default:
264 obj->set_type(Object_Type_VIRTUAL);
265 }
266
267 obj->set_sub_type(obstacle_subtype);
268}
269
270void ObstacleUpdater::SetObstacleSource(const PerceptionObstacle& obstacle,
271 Object* obj) {
272 if (obj == nullptr || !obstacle.has_source()) {
273 return;
274 }
275 const PerceptionObstacle::Source obstacle_source = obstacle.source();
276 obj->set_source(obstacle_source);
277 obj->clear_v2x_info();
278 if (obstacle_source == PerceptionObstacle::V2X && obstacle.has_v2x_info()) {
279 obj->mutable_v2x_info()->CopyFrom(obstacle.v2x_info());
280 }
281 return;
282}
283
284void ObstacleUpdater::SetObstacleSensorMeasurements(
285 const PerceptionObstacle& obstacle, Object* obj,
286 ObstacleChannelUpdater* channel_updater) {
287 if (obj == nullptr) {
288 return;
289 }
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);
302 }
303}
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());
308}
309
310} // namespace dreamview
311} // namespace apollo
Used to perform oneshot or periodic timing tasks
Definition timer.h:71
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.
#define AERROR
Definition log.h:44
Some map util functions.
Some util functions.
class register implement
Definition arena_queue.h:37
std::vector< PerceptionObstacle > obstacles_
std::unique_ptr< cyber::Timer > timer_
std::unordered_map< std::string, Object > obj_map_
optional double heading
Definition pose.proto:48
optional apollo::common::PointENU position
Definition pose.proto:26