Apollo 10.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 : UpdaterWithChannelsBase({"perception.PerceptionObstacles"}, {""}),
37 websocket_(websocket),
38 node_(cyber::CreateNode("obstacle_updater")) {
39 Init();
40}
41
43 localization_reader_ = node_->CreateReader<LocalizationEstimate>(
44 FLAGS_localization_topic,
45 [this](const std::shared_ptr<LocalizationEstimate>& localization) {
46 OnLocalization(localization);
47 });
48}
49ObstacleChannelUpdater* ObstacleUpdater::GetObstacleChannelUpdater(
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] =
54 new ObstacleChannelUpdater(channel_name);
55 obstacle_channel_updater_map_[channel_name]->perception_obstacle_reader_ =
56 node_->CreateReader<PerceptionObstacles>(
57 channel_name,
58 [channel_name,
59 this](const std::shared_ptr<PerceptionObstacles>& obstacles) {
60 OnObstacles(obstacles, channel_name);
61 });
62 }
63 return obstacle_channel_updater_map_[channel_name];
64}
65void ObstacleUpdater::StartStream(const double& time_interval_ms,
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";
70 return;
71 }
72 if (time_interval_ms > 0) {
73 ObstacleChannelUpdater* channel_updater =
74 GetObstacleChannelUpdater(channel_name);
75 if (channel_updater == nullptr) {
76 AERROR << "Failed to subscribe channel: " << channel_name
77 << "for channel updater not registered!";
78 return;
79 }
80 channel_updater->timer_.reset(new cyber::Timer(
81 time_interval_ms,
82 [channel_name, this]() { this->OnTimer(channel_name); }, false));
83 channel_updater->timer_->Start();
84 } else {
85 this->OnTimer(channel_name);
86 }
87}
88
89void ObstacleUpdater::StopStream(const std::string& channel_name) {
90 if (channel_name.empty()) {
91 AERROR << "Failed to unsubscribe channel for channel is empty";
92 return;
93 }
94 if (enabled_) {
95 ObstacleChannelUpdater* channel_updater =
96 GetObstacleChannelUpdater(channel_name);
97 if (channel_updater->timer_) {
98 channel_updater->timer_->Stop();
99 }
100 channel_updater->obj_map_.clear();
101 channel_updater->obstacle_objects_.Clear();
102 channel_updater->obstacles_.clear();
103 }
104}
105
107 if (enabled_) {
108 obstacle_channel_updater_map_.clear();
109 }
110 enabled_ = false;
111}
112
113void ObstacleUpdater::OnTimer(const std::string& channel_name) {
114 PublishMessage(channel_name);
115}
116
117void ObstacleUpdater::PublishMessage(const std::string& channel_name) {
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);
129 websocket_->BroadcastBinaryData(stream_data_string);
130}
131
132void ObstacleUpdater::GetChannelMsg(std::vector<std::string>* channels) {
133 enabled_ = true;
134 GetChannelMsgWithFilter(channels);
135}
136
137void ObstacleUpdater::OnObstacles(
138 const std::shared_ptr<PerceptionObstacles>& obstacles,
139 const std::string& channel) {
140 if (!enabled_) {
141 return;
142 }
143 {
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);
150 }
151 }
152}
153
154void ObstacleUpdater::OnLocalization(
155 const std::shared_ptr<LocalizationEstimate>& localization) {
156 if (!enabled_) {
157 return;
158 }
159 adc_pose_ = localization->pose();
160}
161void ObstacleUpdater::GetObjects(std::string* to_send,
162 std::string channel_name) {
163 {
164 std::lock_guard<std::mutex> lck(updater_publish_mutex_);
165 ObstacleChannelUpdater* channel_updater =
166 GetObstacleChannelUpdater(channel_name);
167
168 if (channel_updater->obstacles_.empty()) {
169 return;
170 }
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);
181 } else {
182 // The object is already in the map.
183 // Only the coordinates of the polygon and its own coordinates are
184 // updated.
185 Object& obj = channel_updater->obj_map_[id];
186 SetObstacleInfo(obstacle, &obj);
187 SetObstaclePolygon(obstacle, &obj);
188 SetObstacleSensorMeasurements(obstacle, &obj, channel_updater);
189 }
190 }
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;
196 }
197 channel_updater->obstacle_objects_.mutable_auto_driving_car()->CopyFrom(
198 auto_driving_car);
199 channel_updater->obstacle_objects_.SerializeToString(to_send);
200 }
201}
202void ObstacleUpdater::SetObstacleInfo(const PerceptionObstacle& obstacle,
203 Object* obj) {
204 if (obj == nullptr) {
205 return;
206 }
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);
219}
220
221void ObstacleUpdater::SetObstaclePolygon(const PerceptionObstacle& obstacle,
222 Object* obj) {
223 if (obj == nullptr) {
224 return;
225 }
226
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);
236 }
237 }
238}
239
240void ObstacleUpdater::SetObstacleType(
241 const PerceptionObstacle::Type obstacle_type,
242 const PerceptionObstacle::SubType obstacle_subtype, Object* obj) {
243 if (obj == nullptr) {
244 return;
245 }
246 switch (obstacle_type) {
248 obj->set_type(Object_Type_UNKNOWN);
249 break;
251 obj->set_type(Object_Type_UNKNOWN_MOVABLE);
252 break;
254 obj->set_type(Object_Type_UNKNOWN_UNMOVABLE);
255 break;
257 obj->set_type(Object_Type_PEDESTRIAN);
258 break;
260 obj->set_type(Object_Type_BICYCLE);
261 break;
263 obj->set_type(Object_Type_VEHICLE);
264 break;
265 default:
266 obj->set_type(Object_Type_VIRTUAL);
267 }
268
269 obj->set_sub_type(obstacle_subtype);
270}
271
272void ObstacleUpdater::SetObstacleSource(const PerceptionObstacle& obstacle,
273 Object* obj) {
274 if (obj == nullptr || !obstacle.has_source()) {
275 return;
276 }
277 const PerceptionObstacle::Source obstacle_source = obstacle.source();
278 obj->set_source(obstacle_source);
279 obj->clear_v2x_info();
280 if (obstacle_source == PerceptionObstacle::V2X && obstacle.has_v2x_info()) {
281 obj->mutable_v2x_info()->CopyFrom(obstacle.v2x_info());
282 }
283 return;
284}
285
286void ObstacleUpdater::SetObstacleSensorMeasurements(
287 const PerceptionObstacle& obstacle, Object* obj,
288 ObstacleChannelUpdater* channel_updater) {
289 if (obj == nullptr) {
290 return;
291 }
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);
304 }
305}
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());
310}
311
312} // namespace dreamview
313} // 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
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.
#define AERROR
Definition log.h:44
Some map util functions.
Some util functions.
std::unique_ptr< Node > CreateNode(const std::string &node_name, const std::string &name_space)
Definition cyber.cc:33
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