Apollo 11.0
自动驾驶开放平台
simulation_world_updater.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2017 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 "google/protobuf/util/json_util.h"
20
21#include "cyber/common/file.h"
28
29namespace apollo {
30namespace dreamview {
31
33using apollo::common::util::ContainsKey;
52
53using Json = nlohmann::json;
54using google::protobuf::util::JsonStringToMessage;
55using google::protobuf::util::MessageToJsonString;
56
58 WebSocketHandler *websocket, WebSocketHandler *map_ws,
59 WebSocketHandler *plugin_ws, const MapService *map_service,
60 PluginManager *plugin_manager, WebSocketHandler *sim_world_ws,
61 HMI *hmi, bool routing_from_file)
62 : sim_world_service_(map_service, routing_from_file),
63 map_service_(map_service),
64 websocket_(websocket),
65 map_ws_(map_ws),
66 plugin_ws_(plugin_ws),
67 // perception_camera_updater_(perception_camera_updater),
68 plugin_manager_(plugin_manager),
69 sim_world_ws_(sim_world_ws),
70 hmi_(hmi),
71 command_id_(0) {
72 RegisterRoutingMessageHandlers();
73 RegisterMessageHandlers();
74}
75
76void SimulationWorldUpdater::RegisterRoutingMessageHandlers() {
77 websocket_->RegisterMessageHandler(
78 "SendRoutingRequest",
79 [this](const Json &json, WebSocketHandler::Connection *conn) {
80 Json response;
81 response["action"] = "response";
82 std::string request_id;
83 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
84 AERROR << "Failed to send routing request: requestId not found.";
85 response["data"]["info"]["code"] = -1;
86 response["data"]["info"]["message"] = "Miss requestId";
87 websocket_->SendData(conn, response.dump());
88 return;
89 }
90 response["data"]["requestId"] = request_id;
91 Json end;
92 std::vector<std::string> json_path = {"data", "info", "end"};
93 if (!JsonUtil::GetJsonByPath(json, json_path, &end)) {
94 AERROR << "Failed to find end: end not found.";
95 response["data"]["info"]["code"] = -1;
96 response["data"]["info"]["message"] = "Miss end";
97 websocket_->SendData(conn, response.dump());
98 return;
99 }
100 std::string parking_space_id =
101 map_service_->GetParkingSpaceId(end["x"], end["y"]);
102 if (parking_space_id != "-1") {
103 // If the parking space ID can be obtained, it means it is a parking
104 // routing
105 auto valet_parking_command = std::make_shared<ValetParkingCommand>();
106 bool succeed = ConstructValetParkingCommand(
107 json, valet_parking_command.get(), parking_space_id);
108 if (succeed) {
109 sim_world_service_.PublishValetParkingCommand(
110 valet_parking_command);
111 sim_world_service_.PublishMonitorMessage(
112 MonitorMessageItem::INFO, "Valet parking command sent.");
113 response["data"]["info"]["code"] = 0;
114 response["data"]["info"]["message"] = "Success";
115 } else {
116 sim_world_service_.PublishMonitorMessage(
118 "Failed to send a Valet parking command.");
119 response["data"]["info"]["code"] = -1;
120 response["data"]["info"]["message"] =
121 "Failed to send a Valet parking command";
122 }
123 websocket_->SendData(conn, response.dump());
124 } else {
125 // Otherwise, it is a normal routing
126 auto lane_follow_command = std::make_shared<LaneFollowCommand>();
127 bool succeed =
128 ConstructLaneFollowCommand(json, lane_follow_command.get());
129 if (succeed) {
130 sim_world_service_.PublishLaneFollowCommand(lane_follow_command);
131 sim_world_service_.PublishMonitorMessage(
132 MonitorMessageItem::INFO, "Lane follow command sent.");
133 response["data"]["info"]["code"] = 0;
134 response["data"]["info"]["message"] = "Success";
135 } else {
136 sim_world_service_.PublishMonitorMessage(
138 "Failed to send a Lane follow command.");
139 response["data"]["info"]["code"] = -1;
140 response["data"]["info"]["message"] =
141 "Failed to send a Lane follow command";
142 }
143 websocket_->SendData(conn, response.dump());
144 }
145 });
146
147 websocket_->RegisterMessageHandler(
148 "SendDefaultCycleRoutingRequest",
149 [this](const Json &json, WebSocketHandler::Connection *conn) {
150 Json response;
151 response["action"] = "response";
152 std::string request_id;
153 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
154 AERROR << "Failed to prepare a cycle lane follow command: requestId "
155 "not found.";
156 response["data"]["info"]["code"] = -1;
157 response["data"]["info"]["message"] = "Miss requestId";
158 websocket_->SendData(conn, response.dump());
159 return;
160 }
161 response["data"]["requestId"] = request_id;
162 Json info;
163 std::vector<std::string> json_path = {"data", "info"};
164 if (!JsonUtil::GetJsonByPath(json, json_path, &info)) {
165 AERROR << "Failed to prepare a cycle lane follow command: info not "
166 "found.";
167 response["data"]["info"]["code"] = -1;
168 response["data"]["info"]["message"] = "Miss info";
169 websocket_->SendData(conn, response.dump());
170 return;
171 }
172 auto task = std::make_shared<Task>();
173 auto *cycle_routing_task = task->mutable_cycle_routing_task();
174 auto *lane_follow_command =
175 cycle_routing_task->mutable_lane_follow_command();
176 if (!ContainsKey(info, "cycleNumber") ||
177 !info.find("cycleNumber")->is_number()) {
178 AERROR
179 << "Failed to prepare a cycle lane follow command: Invalid cycle "
180 "number";
181 response["data"]["info"]["code"] = -1;
182 response["data"]["info"]["message"] = "Invalid cycle number";
183 websocket_->SendData(conn, response.dump());
184 return;
185 }
186 bool succeed = ConstructLaneFollowCommand(json, lane_follow_command);
187 if (succeed) {
188 cycle_routing_task->set_cycle_num(
189 static_cast<int>(info["cycleNumber"]));
190 task->set_task_name("cycle_routing_task");
192 sim_world_service_.PublishTask(task);
193 AINFO << "The task is : " << task->DebugString();
194 sim_world_service_.PublishMonitorMessage(
196 "Default cycle lane follow command sent.");
197 response["data"]["info"]["code"] = 0;
198 response["data"]["info"]["message"] = "Success";
199 } else {
200 sim_world_service_.PublishMonitorMessage(
202 "Failed to send a default cycle lane follow command.");
203 response["data"]["info"]["code"] = -1;
204 response["data"]["info"]["message"] =
205 "Failed to send a default cycle lane follow command";
206 }
207 websocket_->SendData(conn, response.dump());
208 });
209
210 // websocket_->RegisterMessageHandler(
211 // "SendParkGoRoutingRequest",
212 // [this](const Json &json, WebSocketHandler::Connection *conn) {
213 // auto task = std::make_shared<Task>();
214 // auto *park_go_routing_task = task->mutable_park_go_routing_task();
215 // if (!ContainsKey(json, "parkTime") ||
216 // !json.find("parkTime")->is_number()) {
217 // AERROR << "Failed to prepare a park go routing request: Invalid
218 // park "
219 // "time";
220 // return;
221 // }
222 // bool succeed = ConstructRoutingRequest(
223 // json, park_go_routing_task->mutable_routing_request());
224 // if (succeed) {
225 // park_go_routing_task->set_park_time(
226 // static_cast<int>(json["parkTime"]));
227 // task->set_task_name("park_go_routing_task");
228 // task->set_task_type(apollo::task_manager::TaskType::PARK_GO_ROUTING);
229 // sim_world_service_.PublishTask(task);
230 // AINFO << "The task is : " << task->DebugString();
231 // sim_world_service_.PublishMonitorMessage(
232 // MonitorMessageItem::INFO, "Park go routing request sent.");
233 // } else {
234 // sim_world_service_.PublishMonitorMessage(
235 // MonitorMessageItem::ERROR,
236 // "Failed to send a park go routing request.");
237 // }
238 // });
239
240 // websocket_->RegisterMessageHandler(
241 // "SendParkingRoutingRequest",
242 // [this](const Json &json, WebSocketHandler::Connection *conn) {
243 // Json response;
244 // response["action"] = "response";
245 // std::string request_id;
246 // if (!JsonUtil::GetStringByPath(json,
247 // "data.requestId", &request_id)) {
248 // AERROR
249 // << "Failed to send parking routing request:
250 // requestId not found.";
251 // response["data"]["info"]["code"] = -1;
252 // response["data"]["info"]["message"] = "Miss requestId";
253 // websocket_->SendData(conn, response.dump());
254 // return;
255 // }
256 // response["data"]["requestId"] = request_id;
257 // auto valet_parking_command = std::make_shared<ValetParkingCommand>();
258 // bool succeed =
259 // ConstructValetParkingCommand(json, valet_parking_command.get());
260 // if (succeed) {
261 // sim_world_service_.PublishValetParkingCommand(valet_parking_command);
262 // sim_world_service_.PublishMonitorMessage(
263 // MonitorMessageItem::INFO, "Valet parking command sent.");
264 // response["data"]["info"]["code"] = 0;
265 // response["data"]["info"]["message"] = "Success";
266 // } else {
267 // sim_world_service_.PublishMonitorMessage(
268 // MonitorMessageItem::ERROR,
269 // "Failed to send a Valet parking command.");
270 // response["data"]["info"]["code"] = -1;
271 // response["data"]["info"]["message"] =
272 // "Failed to send a Valet parking command";
273 // }
274 // websocket_->SendData(conn, response.dump());
275 // });
276
277 websocket_->RegisterMessageHandler(
278 "GetDefaultRoutings",
279 [this](const Json &json, WebSocketHandler::Connection *conn) {
280 Json response;
281 response["action"] = "response";
282 std::string request_id;
283 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
284 AERROR << "Failed to get default routings: requestId not found.";
285 response["data"]["info"]["code"] = -1;
286 response["data"]["info"]["message"] = "Miss requestId";
287 websocket_->SendData(conn, response.dump());
288 return;
289 }
290 response["data"]["requestId"] = request_id;
291 response["data"]["info"]["threshold"] =
292 FLAGS_loop_routing_end_to_start_distance_threshold;
293 Json default_routing_list = Json::array();
294 if (LoadUserDefinedRoutings(DefaultRoutingFile(), &default_routings_)) {
295 for (const auto &landmark : default_routings_.landmark()) {
296 Json drouting;
297 drouting["name"] = landmark.name();
298
299 Json point_list;
300 for (const auto &point : landmark.waypoint()) {
301 point_list.push_back(GetPointJsonFromLaneWaypoint(point));
302 }
303 drouting["point"] = point_list;
304 if (landmark.has_cycle_number()) {
305 drouting["cycleNumber"] = landmark.cycle_number();
306 }
307
308 default_routing_list.push_back(drouting);
309 }
310 response["data"]["info"]["code"] = 0;
311 response["data"]["info"]["message"] = "Success";
312 } else {
313 sim_world_service_.PublishMonitorMessage(
315 "Failed to load default "
316 "routing. Please make sure the "
317 "file exists at " +
319 response["data"]["info"]["code"] = -1;
320 response["data"]["info"]["message"] =
321 "Failed to load default "
322 "routing. Please make sure the "
323 "file exists at " +
325 }
326 response["data"]["info"]["data"]["defaultRoutings"] =
327 default_routing_list;
328 websocket_->SendData(conn, response.dump());
329 });
330
331 websocket_->RegisterMessageHandler(
332 "GetParkAndGoRoutings",
333 [this](const Json &json, WebSocketHandler::Connection *conn) {
334 Json response;
335 response["type"] = "ParkAndGoRoutings";
336 Json park_go_routing_list = Json::array();
337 if (LoadUserDefinedRoutings(ParkGoRoutingFile(), &park_go_routings_)) {
338 for (const auto &landmark : park_go_routings_.landmark()) {
339 Json park_go_routing;
340 park_go_routing["name"] = landmark.name();
341
342 Json point_list;
343 for (const auto &point : landmark.waypoint()) {
344 point_list.push_back(GetPointJsonFromLaneWaypoint(point));
345 }
346 park_go_routing["point"] = point_list;
347 park_go_routing_list.push_back(park_go_routing);
348 }
349 // } else {
350 // sim_world_service_.PublishMonitorMessage(
351 // MonitorMessageItem::ERROR,
352 // "Failed to load park go "
353 // "routing. Please make sure the "
354 // "file exists at " +
355 // ParkGoRoutingFile());
356 }
357 response["parkAndGoRoutings"] = park_go_routing_list;
358 websocket_->SendData(conn, response.dump());
359 });
360
361 websocket_->RegisterMessageHandler(
362 "SaveDefaultRouting",
363 [this](const Json &json, WebSocketHandler::Connection *conn) {
364 Json response;
365 response["action"] = "response";
366 std::string request_id;
367 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
368 AERROR << "Failed to save default routing: requestId not found.";
369 response["data"]["info"]["code"] = -1;
370 response["data"]["info"]["message"] = "Miss requestId";
371 websocket_->SendData(conn, response.dump());
372 return;
373 }
374 response["data"]["requestId"] = request_id;
375
376 bool succeed = AddDefaultRouting(json);
377 if (succeed) {
378 sim_world_service_.PublishMonitorMessage(
379 MonitorMessageItem::INFO, "Successfully add a routing.");
380 if (!default_routing_) {
381 AERROR << "Failed to add a routing" << std::endl;
382 }
383 Json ret_data = JsonUtil::ProtoToTypedJson("AddDefaultRoutingPath",
384 *default_routing_);
385 response["data"]["info"]["code"] = 0;
386 response["data"]["info"]["message"] = "Success";
387 response["data"]["info"]["data"] = ret_data["data"];
388 } else {
390 "Failed to add a routing.");
391 response["data"]["info"]["code"] = -1;
392 response["data"]["info"]["message"] = "Failed to add a routing";
393 }
394 websocket_->SendData(conn, response.dump());
395 });
396
397 websocket_->RegisterMessageHandler(
398 "DeleteDefaultRouting",
399 [this](const Json &json, WebSocketHandler::Connection *conn) {
400 Json response;
401 response["action"] = "response";
402 std::string request_id, routing_name;
403 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
404 AERROR << "Failed to delete default routing: requestId not found.";
405 response["data"]["info"]["code"] = -1;
406 response["data"]["info"]["message"] = "Miss requestId";
407 websocket_->SendData(conn, response.dump());
408 return;
409 }
410 response["data"]["requestId"] = request_id;
411 if (!JsonUtil::GetStringByPath(json, "data.info.name", &routing_name)) {
412 AERROR << "Failed to delete default routing: name not found.";
413 response["data"]["info"]["code"] = -1;
414 response["data"]["info"]["message"] = "Miss name";
415 websocket_->SendData(conn, response.dump());
416 return;
417 }
418 bool ret = DeleteDefaultRouting(routing_name);
419 if (!ret) {
420 response["data"]["info"]["code"] = -1;
421 response["data"]["info"]["message"] =
422 "Failed to delete default routing";
423 } else {
424 response["data"]["info"]["code"] = 0;
425 response["data"]["info"]["message"] = "Success";
426 }
427 websocket_->SendData(conn, response.dump());
428 });
429}
430
431void SimulationWorldUpdater::RegisterMessageHandlers() {
432 map_ws_->RegisterMessageHandler(
433 "RetrieveMapData",
434 [this](const Json &json, WebSocketHandler::Connection *conn) {
435 auto iter = json.find("elements");
436 if (iter != json.end()) {
437 MapElementIds map_element_ids;
438 if (JsonStringToMessage(iter->dump(), &map_element_ids).ok()) {
439 auto retrieved = map_service_->RetrieveMapElements(map_element_ids);
440
441 std::string retrieved_map_string;
442 retrieved.SerializeToString(&retrieved_map_string);
443
444 map_ws_->SendBinaryData(conn, retrieved_map_string, true);
445 } else {
446 AERROR << "Failed to parse MapElementIds from json";
447 }
448 }
449 });
450
451 map_ws_->RegisterMessageHandler(
452 "RetrieveRelativeMapData",
453 [this](const Json &json, WebSocketHandler::Connection *conn) {
454 std::string to_send;
455 {
456 boost::shared_lock<boost::shared_mutex> reader_lock(mutex_);
457 to_send = relative_map_string_;
458 }
459 map_ws_->SendBinaryData(conn, to_send, true);
460 });
461
462 websocket_->RegisterMessageHandler(
463 "Binary",
464 [this](const std::string &data, WebSocketHandler::Connection *conn) {
465 // Navigation info in binary format
466 auto navigation_info = std::make_shared<NavigationInfo>();
467 if (navigation_info->ParseFromString(data)) {
468 sim_world_service_.PublishNavigationInfo(navigation_info);
469 } else {
470 AERROR << "Failed to parse navigation info from string. String size: "
471 << data.size();
472 }
473 });
474
475 websocket_->RegisterMessageHandler(
476 "RetrieveMapElementIdsByRadius",
477 [this](const Json &json, WebSocketHandler::Connection *conn) {
478 auto radius = json.find("radius");
479 if (radius == json.end()) {
480 AERROR << "Cannot retrieve map elements with unknown radius.";
481 return;
482 }
483
484 if (!radius->is_number()) {
485 AERROR << "Expect radius with type 'number', but was "
486 << radius->type_name();
487 return;
488 }
489
490 Json response;
491 response["type"] = "MapElementIds";
492 response["mapRadius"] = *radius;
493
494 MapElementIds ids;
495 sim_world_service_.GetMapElementIds(*radius, &ids);
496 std::string elementIds;
497 MessageToJsonString(ids, &elementIds);
498 response["mapElementIds"] = Json::parse(elementIds);
499
500 websocket_->SendData(conn, response.dump());
501 });
502
503 websocket_->RegisterMessageHandler(
504 "CheckRoutingPoint",
505 [this](const Json &json, WebSocketHandler::Connection *conn) {
506 Json response;
507 response["action"] = "response";
508 std::string request_id;
509 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
510 AERROR << "Failed to check routing point: requestId not found.";
511 response["data"]["info"]["code"] = -1;
512 response["data"]["info"]["message"] = "Miss requestId";
513 websocket_->SendData(conn, response.dump());
514 return;
515 }
516 response["data"]["requestId"] = request_id;
517 Json result;
518 if (CheckRoutingPoint(json, result)) {
519 response["data"]["info"]["code"] = 0;
520 response["data"]["info"]["message"] = result["message"];
521 response["data"]["info"]["data"]["isLegal"] = result["isLegal"];
522 } else {
523 response["data"]["info"]["code"] = -1;
524 response["data"]["info"]["message"] = result["message"];
525 }
526 websocket_->SendData(conn, response.dump());
527 });
528
529 websocket_->RegisterMessageHandler(
530 "SetStartPoint",
531 [this](const Json &json, WebSocketHandler::Connection *conn) {
532 Json response;
533 std::string request_id;
534 response["action"] = "response";
535 response["data"]["info"] = {};
536 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
537 AERROR << "Miss requestId to reset message";
538 response["data"]["info"]["code"] = -1;
539 response["data"]["info"]["message"] = "Miss requestId";
540 websocket_->SendData(conn, response.dump());
541 return;
542 }
543 response["data"]["requestId"] = request_id;
544 auto sim_control_manager = SimControlManager::Instance();
545 if (!sim_control_manager->IsEnabled()) {
546 AWARN << "Set start point need start sim_control.";
547 response["data"]["info"]["code"] = -1;
548 response["data"]["info"]["message"] =
549 "Failed to set star point for sim control is not enabled!";
550 websocket_->SendData(conn, response.dump());
551 return;
552 }
553 Json point;
554 double x, y, heading;
555 std::vector<std::string> json_path = {"data", "info", "point"};
556 if (!JsonUtil::GetJsonByPath(json, json_path, &point)) {
557 apollo::common::PointENU point_enu;
558 if (!map_service_->GetStartPoint(&point_enu)) {
559 response["data"]["info"]["code"] = -1;
560 response["data"]["info"]["message"] =
561 "Failed to get a dummy start point from map!";
562 websocket_->SendData(conn, response.dump());
563 return;
564 }
565 x = point_enu.x();
566 y = point_enu.y();
567 heading = 0.0;
568 double s = 0.0;
569 map_service_->GetPoseWithRegardToLane(x, y, &heading, &s);
570 } else {
571 if (!JsonUtil::GetNumber(point, "heading", &heading) ||
572 !JsonUtil::GetNumber(point, "x", &x) ||
573 !JsonUtil::GetNumber(point, "y", &y)) {
574 AWARN << "Set start point need start sim_control.";
575 response["data"]["info"]["code"] = -1;
576 response["data"]["info"]["message"] =
577 "Failed to set star point for point field is invalid";
578 websocket_->SendData(conn, response.dump());
579 return;
580 }
581 }
582 sim_control_manager->ReSetPoinstion(x, y, heading);
583 // Send a ActionCommand to clear the trajectory of planning.
584 if (hmi_->isProcessRunning("planning.dag")) {
585 auto action_command = std::make_shared<ActionCommand>();
586 action_command->set_command_id(++command_id_);
587 action_command->set_command(ActionCommandType::CLEAR_PLANNING);
588 sim_world_service_.PublishActionCommand(action_command);
589 }
590 std::string start_str = std::to_string(x) + "," + std::to_string(y) +
591 "," + std::to_string(heading);
592 std::string start_point_file =
593 FLAGS_map_dir + "/" + FLAGS_current_start_point_filename;
594 if (!SetStringToASCIIFile(start_str, start_point_file)) {
595 AERROR << "Failed to set start point to ascii file "
596 << start_point_file;
597 }
598 response["data"]["info"]["code"] = 0;
599 websocket_->SendData(conn, response.dump());
600 return;
601 });
602
603 websocket_->RegisterMessageHandler(
604 "GetMapElementIds",
605 [this](const Json &json, WebSocketHandler::Connection *conn) {
606 Json response;
607 std::string request_id;
608 response["action"] = "response";
609 response["data"]["info"] = {};
610 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
611 AERROR << "Miss requestId to reset message";
612 response["data"]["info"]["code"] = -1;
613 response["data"]["info"]["message"] = "Miss requestId";
614 websocket_->SendData(conn, response.dump());
615 return;
616 }
617 response["data"]["requestId"] = request_id;
618 double radius;
619 if (!JsonUtil::GetNumberByPath(json, "data.info.radius", &radius)) {
620 AWARN << "Collect map element ids need radius info.";
621 response["data"]["info"]["code"] = -1;
622 response["data"]["info"]["message"] =
623 "Failed to collect map element ids for radius field is missed.";
624 websocket_->SendData(conn, response.dump());
625 return;
626 }
627 Json point;
628 apollo::common::PointENU point_enu;
629 std::vector<std::string> json_path = {"data", "info", "point"};
630 if (!JsonUtil::GetJsonByPath(json, json_path, &point)) {
631 AERROR << "Miss point field to set start point,use map service to "
632 "find start point.";
633 if (!map_service_->GetStartPoint(&point_enu)) {
634 response["data"]["info"]["code"] = -1;
635 response["data"]["info"]["message"] =
636 "Failed to collect map element ids for failed to get a dummy "
637 "start point from map!";
638 websocket_->SendData(conn, response.dump());
639 return;
640 }
641 } else {
642 double x, y, z;
643 if (!JsonUtil::GetNumber(point, "x", &x) ||
644 !JsonUtil::GetNumber(point, "y", &y) ||
645 !JsonUtil::GetNumberByPath(json, "data.info.radius", &radius)) {
646 response["data"]["info"]["code"] = -1;
647 response["data"]["info"]["message"] =
648 "Failed to collect map element ids for point field is invalid.";
649 websocket_->SendData(conn, response.dump());
650 return;
651 }
652 point_enu.set_x(x);
653 point_enu.set_y(y);
654 if (JsonUtil::GetNumber(point, "z", &z)) {
655 point_enu.set_z(z);
656 }
657 }
658 MapElementIds map_element_ids;
659 map_service_->CollectMapElementIds(point_enu, radius, &map_element_ids);
660 response["data"]["info"]["data"] =
661 JsonUtil::ProtoToJson(map_element_ids);
662 response["data"]["info"]["code"] = 0;
663 websocket_->SendData(conn, response.dump());
664 return;
665 });
666
667 websocket_->RegisterMessageHandler(
668 "GetMapElementsByIds",
669 [this](const Json &json, WebSocketHandler::Connection *conn) {
670 Json response;
671 std::string request_id;
672 response["action"] = "response";
673 response["data"]["info"] = {};
674 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
675 AERROR << "Miss requestId to reset message";
676 response["data"]["info"]["code"] = -1;
677 response["data"]["info"]["message"] = "Miss requestId";
678 websocket_->SendData(conn, response.dump());
679 return;
680 }
681 response["data"]["requestId"] = request_id;
682 Json element_ids_json;
683 if (!JsonUtil::GetJsonByPath(json,
684 {"data", "info", "param", "mapElementIds"},
685 &element_ids_json)) {
686 response["data"]["info"]["code"] = -1;
687 response["data"]["info"]["message"] = "Miss map elementIds";
688 websocket_->SendData(conn, response.dump());
689 return;
690 }
691 MapElementIds map_element_ids;
692 if (!JsonStringToMessage(element_ids_json.dump(), &map_element_ids)
693 .ok()) {
694 response["data"]["info"]["code"] = -1;
695 response["data"]["info"]["message"] =
696 "Failed to parse elementIds from json.";
697 websocket_->SendData(conn, response.dump());
698 return;
699 }
700 auto retrieved = map_service_->RetrieveMapElements(map_element_ids);
701 // std::string retrieved_map_string;
702 // retrieved.SerializeToString(&retrieved_map_string);
703 response["data"]["info"]["data"] = JsonUtil::ProtoToJson(retrieved);
704 response["data"]["info"]["code"] = 0;
705 websocket_->SendData(conn, response.dump());
706 return;
707 });
708
709 websocket_->RegisterMessageHandler(
710 "GetStartPoint",
711 [this](const Json &json, WebSocketHandler::Connection *conn) {
712 Json response;
713 std::string request_id;
714 response["action"] = "response";
715 response["data"]["info"] = {};
716 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
717 AERROR << "Miss requestId to reset message";
718 response["data"]["info"]["code"] = -1;
719 response["data"]["info"]["message"] = "Miss requestId";
720 websocket_->SendData(conn, response.dump());
721 return;
722 }
723 response["data"]["requestId"] = request_id;
724 Object adc = sim_world_service_.world().auto_driving_car();
725 if (!adc.has_position_x() || !adc.has_position_y()) {
726 response["data"]["info"]["code"] = -1;
727 response["data"]["info"]["message"] = "Miss adc position x,y val";
728 websocket_->SendData(conn, response.dump());
729 return;
730 }
731 response["data"]["info"]["code"] = 0;
732 Json start_point({});
733 start_point["x"] = adc.position_x();
734 start_point["y"] = adc.position_y();
735 if (adc.has_heading()) {
736 start_point["heading"] = adc.heading();
737 }
738 response["data"]["info"]["data"] = start_point;
739 websocket_->SendData(conn, response.dump());
740 return;
741 });
742
743 websocket_->RegisterMessageHandler(
744 "RequestRoutePath",
745 [this](const Json &json, WebSocketHandler::Connection *conn) {
746 Json response;
747 response["action"] = "response";
748 std::string request_id;
749 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
750 AERROR << "Failed to request route path: requestId not found.";
751 response["data"]["info"]["code"] = -1;
752 response["data"]["info"]["message"] = "Miss requestId";
753 websocket_->SendData(conn, response.dump());
754 return;
755 }
756 response["data"]["requestId"] = request_id;
757 Json result = sim_world_service_.GetRoutePathAsJson();
758 response["data"]["info"]["code"] = 0;
759 response["data"]["info"]["message"] = "Success";
760 response["data"]["info"]["data"] = result;
761 websocket_->SendData(conn, response.dump());
762 });
763
764 // websocket_->RegisterMessageHandler(
765 // "GetDefaultEndPoint",
766 // [this](const Json &json, WebSocketHandler::Connection *conn) {
767 // Json response;
768 // response["action"] = "response";
769 // std::string request_id;
770 // if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id))
771 // {
772 // AERROR << "Failed to get default end point: requestId not found.";
773 // response["data"]["info"]["code"] = -1;
774 // response["data"]["info"]["message"] = "Miss requestId";
775 // websocket_->SendData(conn, response.dump());
776 // return;
777 // }
778 // response["data"]["requestId"] = request_id;
779
780 // Json poi_list = Json::array();
781 // if (LoadPOI()) {
782 // for (const auto &landmark : poi_.landmark()) {
783 // Json place;
784 // place["name"] = landmark.name();
785
786 // Json parking_info =
787 // apollo::common::util::JsonUtil::ProtoToTypedJson(
788 // "parkingInfo", landmark.parking_info());
789 // place["parkingInfo"] = parking_info["data"];
790
791 // Json waypoint_list;
792 // for (const auto &waypoint : landmark.waypoint()) {
793 // waypoint_list.push_back(GetPointJsonFromLaneWaypoint(waypoint));
794 // }
795 // place["waypoint"] = waypoint_list;
796
797 // poi_list.push_back(place);
798 // }
799 // response["data"]["info"]["code"] = 0;
800 // response["data"]["info"]["message"] = "Success";
801 // } else {
802 // sim_world_service_.PublishMonitorMessage(MonitorMessageItem::ERROR,
803 // "Failed to load default "
804 // "POI. Please make sure the
805 // " "file exists at " +
806 // EndWayPointFile());
807 // response["data"]["info"]["code"] = -1;
808 // response["data"]["info"]["message"] = "Failed to load default "
809 // "POI. Please make sure the
810 // " "file exists at " +
811 // EndWayPointFile();
812 // }
813 // response["data"]["info"]["poi"] = poi_list;
814 // websocket_->SendData(conn, response.dump());
815 // });
816
817 websocket_->RegisterMessageHandler(
818 "Reset", [this](const Json &json, WebSocketHandler::Connection *conn) {
819 Json response({});
820 std::string request_id;
821 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
822 AERROR << "Miss requestId to reset message";
823 response["action"] = "response";
824 response["data"]["info"]["code"] = -1;
825 response["data"]["info"]["message"] = "Miss requestId";
826 websocket_->SendData(conn, response.dump());
827 return;
828 }
829 sim_world_service_.SetToClear();
830 SimControlManager::Instance()->Reset();
831 response["action"] = "response";
832 response["data"]["info"]["code"] = 0;
833 response["data"]["info"]["message"] = "Success";
834 response["data"]["requestId"] = request_id;
835 websocket_->SendData(conn, response.dump());
836 });
837
838 websocket_->RegisterMessageHandler(
839 "Dump", [this](const Json &json, WebSocketHandler::Connection *conn) {
840 Json response({});
841 std::string request_id;
842 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
843 AERROR << "Miss requestId to dump message";
844 response["action"] = "response";
845 response["data"]["info"]["code"] = -1;
846 response["data"]["info"]["message"] = "Miss requestId";
847 websocket_->SendData(conn, response.dump());
848 return;
849 }
850 sim_world_service_.DumpMessages();
851 response["action"] = "response";
852 response["data"]["info"]["code"] = 0;
853 response["data"]["info"]["message"] = "Success";
854 response["data"]["requestId"] = request_id;
855 websocket_->SendData(conn, response.dump());
856 });
857
858 websocket_->RegisterMessageHandler(
859 "GetParkingRoutingDistance",
860 [this](const Json &json, WebSocketHandler::Connection *conn) {
861 Json response;
862 response["type"] = "ParkingRoutingDistance";
863 response["threshold"] = FLAGS_parking_routing_distance_threshold;
864 websocket_->SendData(conn, response.dump());
865 });
866
867 // websocket_->RegisterMessageHandler(
868 // "ModifyDefaultRoutingCycleNumber",
869 // [this](const Json &json, WebSocketHandler::Connection *conn) {
870 // Json response;
871 // response["action"] = "response";
872 // std::string request_id;
873 // if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id))
874 // {
875 // AERROR << "Failed to save default routing: requestId not found.";
876 // response["data"]["info"]["code"] = -1;
877 // response["data"]["info"]["message"] = "Miss requestId";
878 // websocket_->SendData(conn, response.dump());
879 // return;
880 // }
881 // response["data"]["requestId"] = request_id;
882 // std::string routing_name;
883 // if (!JsonUtil::GetStringByPath(json, "data.info.name",
884 // &routing_name)) {
885 // AERROR << "Failed to delete default routing: name not found.";
886 // response["data"]["info"]["code"] = -1;
887 // response["data"]["info"]["message"] = "Miss name";
888 // websocket_->SendData(conn, response.dump());
889 // return;
890 // } else if (!ContainsKey(json["data"]["info"], "cycleNumber") ||
891 // !json["data"]["info"].find("cycleNumber")->is_number()) {
892 // AERROR
893 // << "Failed to prepare a cycle lane follow command: Invalid
894 // cycle "
895 // "number";
896 // response["data"]["info"]["code"] = -1;
897 // response["data"]["info"]["message"] = "Invalid cycle number";
898 // websocket_->SendData(conn, response.dump());
899 // return;
900 // }
901 // int cycle_number =
902 // static_cast<int>(json["data"]["info"]["cycleNumber"]);
903 // bool ret = ModifyCycleNumber(routing_name, cycle_number);
904 // if (!ret) {
905 // response["data"]["info"]["code"] = -1;
906 // response["data"]["info"]["message"] =
907 // "Failed to modify default routing cycle number";
908 // } else {
909 // response["data"]["info"]["code"] = 0;
910 // response["data"]["info"]["message"] = "Success";
911 // }
912 // websocket_->SendData(conn, response.dump());
913 // });
914
915 websocket_->RegisterMessageHandler(
916 "CheckCycleRouting",
917 [this](const Json &json, WebSocketHandler::Connection *conn) {
918 Json response, result;
919 response["action"] = "response";
920 std::string request_id;
921 if (!JsonUtil::GetStringByPath(json, "data.requestId", &request_id)) {
922 AERROR << "Failed to check cycle routing: requestId not found.";
923 response["data"]["info"]["code"] = -1;
924 response["data"]["info"]["message"] = "Miss requestId";
925 websocket_->SendData(conn, response.dump());
926 return;
927 }
928 response["data"]["requestId"] = request_id;
929 if (CheckCycleRouting(json, result)) {
930 response["data"]["info"]["code"] = 0;
931 response["data"]["info"]["data"]["isCycle"] = result["isCycle"];
932 response["data"]["info"]["message"] = result["message"];
933 } else {
934 response["data"]["info"]["code"] = -1;
935 response["data"]["info"]["message"] = result["message"];
936 }
937 websocket_->SendData(conn, response.dump());
938 });
939
940 plugin_ws_->RegisterMessageHandler(
941 "PluginRequest",
942 [this](const Json &json, WebSocketHandler::Connection *conn) {
943 if (!plugin_manager_->IsEnabled()) {
944 return;
945 }
946 auto iter = json.find("data");
947 if (iter == json.end()) {
948 AERROR << "Failed to get plugin msg!";
949 return;
950 }
951 if (!plugin_manager_->SendMsgToPlugin(iter->dump())) {
952 AERROR << "Failed to send msg to plugin";
953 }
954 });
955}
956
957bool SimulationWorldUpdater::CheckRoutingPoint(const nlohmann::json &json,
958 nlohmann::json &result) {
959 Json point;
960 std::vector<std::string> json_path = {"data", "info", "point"};
961 if (!JsonUtil::GetJsonByPath(json, json_path, &point)) {
962 result["message"] = "Failed to check routing point: point not found.";
963 AERROR << result["message"];
964 return false;
965 }
966
967 if (!ValidateCoordinate(point) || !ContainsKey(point, "id")) {
968 result["message"] = "Failed to check routing point: invalid point.";
969 AERROR << result["message"];
970 return false;
971 }
972 if (!ContainsKey(point, "heading")) {
973 if (!map_service_->CheckRoutingPoint(point["x"], point["y"])) {
974 result["pointId"] = point["id"];
975 result["isLegal"] = 0;
976 result["message"] = "Selected point cannot be a routing point.";
977 AWARN << result["message"];
978 return true;
979 }
980 } else {
981 if (!map_service_->CheckRoutingPointWithHeading(point["x"], point["y"],
982 point["heading"])) {
983 result["pointId"] = point["id"];
984 result["isLegal"] = 0;
985 result["message"] = "Selected point cannot be a routing point.";
986 AWARN << result["message"];
987 return true;
988 }
989 }
990 result["isLegal"] = 1;
991 result["message"] = "Success";
992 return true;
993}
994
995Json SimulationWorldUpdater::GetPointJsonFromLaneWaypoint(
996 const apollo::routing::LaneWaypoint &waypoint) {
997 Json point;
998 point["x"] = waypoint.pose().x();
999 point["y"] = waypoint.pose().y();
1000 if (waypoint.has_heading()) {
1001 point["heading"] = waypoint.heading();
1002 }
1003 return point;
1004}
1005
1006bool SimulationWorldUpdater::ConstructLaneWayPoint(const Json &point,
1007 LaneWaypoint *laneWayPoint,
1008 std::string description) {
1009 if (ContainsKey(point, "heading")) {
1010 if (!map_service_->ConstructLaneWayPointWithHeading(
1011 point["x"], point["y"], point["heading"], laneWayPoint)) {
1012 AERROR << "Failed to prepare a routing request with heading: "
1013 << point["heading"] << " cannot locate " << description
1014 << " on map.";
1015 return false;
1016 }
1017 } else {
1018 if (!map_service_->ConstructLaneWayPoint(point["x"], point["y"],
1019 laneWayPoint)) {
1020 AERROR << "Failed to prepare a routing request:"
1021 << " cannot locate " << description << " on map.";
1022 return false;
1023 }
1024 }
1025 return true;
1026}
1027
1028bool SimulationWorldUpdater::ConstructLaneFollowCommand(
1029 const Json &json, LaneFollowCommand *lane_follow_command) {
1030 if (!ContainsKey(json, "data")) {
1031 AERROR << "Failed to prepare a cycle lane follow command: data not found.";
1032 return false;
1033 } else if (!ContainsKey(json["data"], "info")) {
1034 AERROR << "Failed to prepare a cycle lane follow command: info not found.";
1035 return false;
1036 }
1037 lane_follow_command->set_command_id(++command_id_);
1038
1039 auto iter = json["data"]["info"].find("waypoint");
1040 if (iter != json["data"]["info"].end() && iter->is_array()) {
1041 auto waypoint = lane_follow_command->mutable_way_point();
1042 for (size_t i = 0; i < iter->size(); ++i) {
1043 auto &point = (*iter)[i];
1044 auto *pose = waypoint->Add();
1045 pose->set_x(point["x"]);
1046 pose->set_y(point["y"]);
1047 }
1048 }
1049
1050 // set end point
1051 if (!ContainsKey(json["data"]["info"], "end")) {
1052 AERROR << "Failed to prepare a routing request: end point not found.";
1053 return false;
1054 }
1055
1056 auto end = json["data"]["info"]["end"];
1057 if (!ValidateCoordinate(end)) {
1058 AERROR << "Failed to prepare a routing request: invalid end point.";
1059 return false;
1060 }
1061 auto end_pose = lane_follow_command->mutable_end_pose();
1062 end_pose->Clear();
1063 if (ContainsKey(end, "heading")) {
1064 end_pose->set_heading(end["heading"]);
1065 }
1066 end_pose->set_x(end["x"]);
1067 end_pose->set_y(end["y"]);
1068
1069 AINFO << "Constructed LaneFollowCommand to be sent:\n"
1070 << lane_follow_command->DebugString();
1071
1072 return true;
1073}
1074
1075bool SimulationWorldUpdater::ConstructValetParkingCommand(
1076 const Json &json, ValetParkingCommand *valet_parking_command,
1077 const std::string &parking_space_id) {
1078 valet_parking_command->clear_parking_spot_id();
1079 valet_parking_command->set_command_id(++command_id_);
1080 valet_parking_command->set_parking_spot_id(parking_space_id);
1081 AINFO << "Constructed ValetParkingCommand to be sent:\n"
1082 << valet_parking_command->DebugString();
1083 return true;
1084}
1085
1086Json SimulationWorldUpdater::GetConstructRoutingRequestJson(
1087 const nlohmann::json &start, const nlohmann::json &end) {
1088 Json result;
1089 result["start"] = start;
1090 result["end"] = end;
1091 return result;
1092}
1093
1094bool SimulationWorldUpdater::ValidateCoordinate(const nlohmann::json &json) {
1095 if (!ContainsKey(json, "x") || !ContainsKey(json, "y")) {
1096 AERROR << "Failed to find x or y coordinate.";
1097 return false;
1098 }
1099 if (json.find("x")->is_number() && json.find("y")->is_number()) {
1100 return true;
1101 }
1102 AERROR << "Both x and y coordinate should be a number.";
1103 return false;
1104}
1105
1106void SimulationWorldUpdater::StartStream(const double &time_interval_ms,
1107 const std::string &channel_name,
1108 nlohmann::json *subscribe_param) {
1109 AINFO << "Start SimulationWorld updater with data sending frequency: "
1110 << time_interval_ms;
1111 time_interval_ms_ = time_interval_ms;
1112 if (time_interval_ms_ > 0) {
1113 timer_.reset(new cyber::Timer(
1114 time_interval_ms, [this]() { this->OnTimer(); }, false));
1115 timer_->Start();
1116 } else {
1117 this->OnTimer();
1118 }
1119}
1120
1121void SimulationWorldUpdater::StopStream(const std::string &channel_name) {
1122 AINFO << "SimulationWorld updater has been stopped";
1123 if (timer_) {
1124 timer_->Stop();
1125 }
1126}
1127
1128void SimulationWorldUpdater::OnTimer(const std::string &channel_name) {
1129 sim_world_service_.Update();
1130 {
1131 boost::unique_lock<boost::shared_mutex> writer_lock(mutex_);
1132 last_pushed_adc_timestamp_sec_ =
1133 sim_world_service_.world().auto_driving_car().timestamp_sec();
1134 sim_world_service_.GetWireFormatString(
1135 FLAGS_sim_map_radius, &simulation_world_with_planning_data_);
1136 sim_world_service_.GetRelativeMap().SerializeToString(
1137 &relative_map_string_);
1138 }
1139 PublishMessage();
1140}
1141
1142void SimulationWorldUpdater::PublishMessage(const std::string &channel_name) {
1143 if (!sim_world_service_.ReadyToPush()) {
1144 AWARN_EVERY(time_interval_ms_);
1145 return;
1146 }
1147 std::string to_send;
1148 {
1149 boost::shared_lock<boost::shared_mutex> writer_lock(mutex_);
1150 to_send = simulation_world_with_planning_data_;
1151 }
1152 StreamData stream_data;
1153 std::string stream_data_string;
1154 stream_data.set_action("stream");
1155 stream_data.set_data_name("simworld");
1156 std::vector<uint8_t> byte_data(to_send.begin(), to_send.end());
1157 stream_data.set_data(&(byte_data[0]), byte_data.size());
1158 stream_data.set_type("simworld");
1159 stream_data.SerializeToString(&stream_data_string);
1160 sim_world_ws_->BroadcastBinaryData(stream_data_string);
1161}
1162
1163bool SimulationWorldUpdater::LoadPOI() {
1164 if (GetProtoFromASCIIFile(EndWayPointFile(), &poi_)) {
1165 return true;
1166 }
1167
1168 AWARN << "Failed to load default list of POI from " << EndWayPointFile();
1169 return false;
1170}
1171
1172bool SimulationWorldUpdater::LoadUserDefinedRoutings(
1173 const std::string &file_name, google::protobuf::Message *message) {
1174 message->Clear();
1175 if (GetProtoFromASCIIFile(file_name, message)) {
1176 return true;
1177 }
1178
1179 AWARN << "Failed to load routings from " << file_name;
1180 return false;
1181}
1182
1183bool SimulationWorldUpdater::AddDefaultRouting(const Json &json) {
1184 if (!ContainsKey(json, "data")) {
1185 AERROR << "Failed to save a routing: data not found.";
1186 return false;
1187 }
1188
1189 if (!ContainsKey(json["data"], "info")) {
1190 AERROR << "Failed to save a routing: info not found.";
1191 return false;
1192 }
1193
1194 if (!ContainsKey(json["data"]["info"], "name")) {
1195 AERROR << "Failed to save a routing: routing name not found.";
1196 return false;
1197 }
1198
1199 if (!ContainsKey(json["data"]["info"], "point")) {
1200 AERROR << "Failed to save a routing: routing points not "
1201 "found.";
1202 return false;
1203 }
1204
1205 if (!ContainsKey(json["data"]["info"], "routingType")) {
1206 AERROR << "Failed to save a routing: routing type not "
1207 "found.";
1208 return false;
1209 }
1210 std::string name = json["data"]["info"]["name"];
1211 auto iter = json["data"]["info"].find("point");
1212 std::string routingType = json["data"]["info"]["routingType"];
1213 bool isDefaultRouting = (routingType == "defaultRouting");
1214 default_routing_ = isDefaultRouting ? default_routings_.add_landmark()
1215 : park_go_routings_.add_landmark();
1216 default_routing_->clear_name();
1217 default_routing_->clear_waypoint();
1218 default_routing_->set_name(name);
1219 auto *waypoint = default_routing_->mutable_waypoint();
1220 if (iter != json["data"]["info"].end() && iter->is_array()) {
1221 for (size_t i = 0; i < iter->size(); ++i) {
1222 auto &point = (*iter)[i];
1223 if (!ValidateCoordinate(point)) {
1224 AERROR << "Failed to save a routing: invalid waypoint.";
1225 return false;
1226 }
1227 auto *p = waypoint->Add();
1228 auto *pose = p->mutable_pose();
1229 pose->set_x(static_cast<double>(point["x"]));
1230 pose->set_y(static_cast<double>(point["y"]));
1231 if (ContainsKey(point, "heading")) {
1232 p->set_heading(point["heading"]);
1233 }
1234 }
1235 }
1236 if (ContainsKey(json["data"]["info"], "cycleNumber") &&
1237 !json["data"]["info"].find("cycleNumber")->is_number()) {
1238 AERROR << "Failed to save a routing: Invalid cycle number";
1239 return false;
1240 } else if (ContainsKey(json["data"]["info"], "cycleNumber")) {
1241 default_routing_->clear_cycle_number();
1242 default_routing_->set_cycle_number(
1243 static_cast<int>(json["data"]["info"]["cycleNumber"]));
1244 }
1245 AINFO << "User Defined Routing Points to be saved:\n";
1246 std::string file_name =
1247 isDefaultRouting ? DefaultRoutingFile() : ParkGoRoutingFile();
1249 isDefaultRouting ? default_routings_ : park_go_routings_,
1250 file_name)) {
1251 AERROR << "Failed to set proto to ascii file " << file_name;
1252 return false;
1253 }
1254 AINFO << "Success in setting proto to file" << file_name;
1255
1256 return true;
1257}
1258
1259bool SimulationWorldUpdater::DeleteDefaultRouting(
1260 const std::string &routing_name) {
1261 /*
1262 According to the interaction, before deleting or adding,
1263 the list of current default routes must be obtained first,
1264 so just modify the current "default_routes" as adding, and then rewrite it.
1265 */
1266
1267 apollo::routing::POI ret_default_routings;
1268 for (auto &landmark : default_routings_.landmark()) {
1269 if (landmark.name() == routing_name) {
1270 continue;
1271 }
1272 ret_default_routings.add_landmark();
1273 ret_default_routings
1274 .mutable_landmark(ret_default_routings.landmark_size() - 1)
1275 ->CopyFrom(landmark);
1276 }
1277 default_routings_.clear_landmark();
1278 default_routings_.mutable_landmark()->CopyFrom(
1279 ret_default_routings.landmark());
1280
1281 if (!SetProtoToASCIIFile(default_routings_, DefaultRoutingFile())) {
1282 AERROR << "Failed to set proto to ascii file " << DefaultRoutingFile();
1283 return false;
1284 }
1285 return true;
1286}
1287
1288// bool SimulationWorldUpdater::ModifyCycleNumber(const std::string
1289// &routing_name,
1290// const int &cycle_number) {
1291// for (int i = 0; i < default_routings_.landmark_size(); i++) {
1292// if (default_routings_.landmark(i).name() == routing_name) {
1293// default_routings_.mutable_landmark(i)->set_cycle_number(cycle_number);
1294// break;
1295// }
1296// }
1297// if (!SetProtoToASCIIFile(default_routings_, DefaultRoutingFile())) {
1298// AERROR << "Failed to set proto to ascii file " << DefaultRoutingFile();
1299// return false;
1300// }
1301// return true;
1302// }
1303
1304bool SimulationWorldUpdater::CheckCycleRouting(const Json &json,
1305 nlohmann::json &result) {
1306 Json start_json, end_json;
1307 std::vector<std::string> json_path = {"data", "info", "start"};
1308 if (!JsonUtil::GetJsonByPath(json, json_path, &start_json)) {
1309 AERROR << "Failed to check cycle routing: Miss start point.";
1310 result["message"] = "Miss start point";
1311 return false;
1312 }
1313 json_path[json_path.size() - 1] = "end";
1314 if (!JsonUtil::GetJsonByPath(json, json_path, &end_json)) {
1315 AERROR << "Failed to check cycle routing: Miss end point.";
1316 result["message"] = "Miss end point";
1317 return false;
1318 }
1320 if (JsonStringToMessage(start_json.dump(), &start).ok() &&
1321 JsonStringToMessage(end_json.dump(), &end).ok()) {
1322 double x_dis = start.x() - end.x();
1323 double y_dis = start.y() - end.y();
1324 if (x_dis * x_dis + y_dis * y_dis <
1325 FLAGS_threshold_for_destination_check *
1326 FLAGS_threshold_for_destination_check) {
1327 result["message"] = "Success";
1328 result["isCycle"] = 1;
1329 return true;
1330 }
1331 result["message"] = "Unable to form a cycle routing";
1332 result["isCycle"] = 0;
1333 return true;
1334 }
1335 AERROR << "Failed to parse MapElementIds from json";
1336 result["message"] = "Failed to parse MapElementIds from json";
1337 return false;
1338}
1339
1340} // namespace dreamview
1341} // namespace apollo
static bool GetNumber(const nlohmann::json &json, const std::string &key, T *value)
Get a number value from the given json[key].
Definition json_util.h:59
static bool GetStringByPath(const nlohmann::json &json, const std::string &path, std::string *value)
Get a string value from the given json and path.
Definition json_util.cc:97
static nlohmann::json ProtoToJson(const google::protobuf::Message &proto)
Convert proto to a json string.
Definition json_util.cc:50
static bool GetJsonByPath(const nlohmann::json &json, const std::vector< std::string > &paths, nlohmann::json *value)
Get the json from the given json and path.
Definition json_util.cc:73
static nlohmann::json ProtoToTypedJson(const std::string &json_type, const google::protobuf::Message &proto)
Convert proto to a json string.
Definition json_util.cc:37
static bool GetNumberByPath(const nlohmann::json &json, const std::string &path, T *value)
Get a number value from the given json and path.
Definition json_util.h:120
Used to perform oneshot or periodic timing tasks
Definition timer.h:71
std::string GetParkingSpaceId(const double x, const double y) const
void PublishTask(const std::shared_ptr< apollo::task_manager::Task > &)
void PublishLaneFollowCommand(const std::shared_ptr< apollo::external_command::LaneFollowCommand > &)
void PublishMonitorMessage(apollo::common::monitor::MonitorMessageItem::LogLevel log_level, const std::string &msg)
Publish message to the monitor
void PublishValetParkingCommand(const std::shared_ptr< apollo::external_command::ValetParkingCommand > &)
SimulationWorldUpdater(WebSocketHandler *websocket, WebSocketHandler *map_ws, WebSocketHandler *camera_ws, WebSocketHandler *plugin_ws, const MapService *map_service, PerceptionCameraUpdater *perception_camera_updater, PluginManager *plugin_manager, bool routing_from_file=false)
Constructor with the websocket handler.
The WebSocketHandler, built on top of CivetWebSocketHandler, is a websocket handler that handles diff...
void RegisterMessageHandler(std::string type, MessageHandler handler)
Add a new message handler for a message type.
bool SendData(Connection *conn, const std::string &data, bool skippable=false, int op_code=MG_WEBSOCKET_OPCODE_TEXT)
Sends the provided data to a specific connected client.
#define AERROR
Definition log.h:44
#define AWARN_EVERY(freq)
Definition log.h:84
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
Some map util functions.
nlohmann::json Json
bool GetProtoFromASCIIFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as ascii representation of protobufs,...
Definition file.cc:89
bool SetStringToASCIIFile(const std::string &content, const std::string &file_name)
Sets the content of the file specified by the file_name to be the ascii representation of the input s...
Definition file.cc:69
bool SetProtoToASCIIFile(const google::protobuf::Message &message, int file_descriptor)
Definition file.cc:43
std::string DefaultRoutingFile()
get default routing file path from flags.
Definition hdmap_util.h:68
std::string EndWayPointFile()
get end way point file path from flags.
Definition hdmap_util.h:56
std::string ParkGoRoutingFile()
get park and go routings file path from flags.
Definition hdmap_util.h:76
class register implement
Definition arena_queue.h:37
optional apollo::common::PointENU pose
repeated Landmark landmark
Definition poi.proto:31