19#include "google/protobuf/util/json_util.h"
33using apollo::common::util::ContainsKey;
53using Json = nlohmann::json;
54using google::protobuf::util::JsonStringToMessage;
55using google::protobuf::util::MessageToJsonString;
61 HMI *hmi,
bool routing_from_file)
62 : sim_world_service_(map_service, routing_from_file),
63 map_service_(map_service),
64 websocket_(websocket),
66 plugin_ws_(plugin_ws),
68 plugin_manager_(plugin_manager),
69 sim_world_ws_(sim_world_ws),
72 RegisterRoutingMessageHandlers();
73 RegisterMessageHandlers();
76void SimulationWorldUpdater::RegisterRoutingMessageHandlers() {
81 response[
"action"] =
"response";
82 std::string 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());
90 response[
"data"][
"requestId"] = request_id;
92 std::vector<std::string> json_path = {
"data",
"info",
"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());
100 std::string parking_space_id =
102 if (parking_space_id !=
"-1") {
105 auto valet_parking_command = std::make_shared<ValetParkingCommand>();
106 bool succeed = ConstructValetParkingCommand(
107 json, valet_parking_command.get(), parking_space_id);
110 valet_parking_command);
113 response[
"data"][
"info"][
"code"] = 0;
114 response[
"data"][
"info"][
"message"] =
"Success";
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";
123 websocket_->
SendData(conn, response.dump());
126 auto lane_follow_command = std::make_shared<LaneFollowCommand>();
128 ConstructLaneFollowCommand(json, lane_follow_command.get());
133 response[
"data"][
"info"][
"code"] = 0;
134 response[
"data"][
"info"][
"message"] =
"Success";
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";
143 websocket_->
SendData(conn, response.dump());
148 "SendDefaultCycleRoutingRequest",
151 response[
"action"] =
"response";
152 std::string request_id;
154 AERROR <<
"Failed to prepare a cycle lane follow command: requestId "
156 response[
"data"][
"info"][
"code"] = -1;
157 response[
"data"][
"info"][
"message"] =
"Miss requestId";
158 websocket_->
SendData(conn, response.dump());
161 response[
"data"][
"requestId"] = request_id;
163 std::vector<std::string> json_path = {
"data",
"info"};
165 AERROR <<
"Failed to prepare a cycle lane follow command: info not "
167 response[
"data"][
"info"][
"code"] = -1;
168 response[
"data"][
"info"][
"message"] =
"Miss info";
169 websocket_->
SendData(conn, response.dump());
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()) {
179 <<
"Failed to prepare a cycle lane follow command: Invalid cycle "
181 response[
"data"][
"info"][
"code"] = -1;
182 response[
"data"][
"info"][
"message"] =
"Invalid cycle number";
183 websocket_->
SendData(conn, response.dump());
186 bool succeed = ConstructLaneFollowCommand(json, lane_follow_command);
188 cycle_routing_task->set_cycle_num(
189 static_cast<int>(info[
"cycleNumber"]));
190 task->set_task_name(
"cycle_routing_task");
193 AINFO <<
"The task is : " << task->DebugString();
196 "Default cycle lane follow command sent.");
197 response[
"data"][
"info"][
"code"] = 0;
198 response[
"data"][
"info"][
"message"] =
"Success";
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";
207 websocket_->
SendData(conn, response.dump());
278 "GetDefaultRoutings",
281 response[
"action"] =
"response";
282 std::string 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());
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();
295 for (
const auto &landmark : default_routings_.landmark()) {
297 drouting[
"name"] = landmark.name();
300 for (
const auto &point : landmark.waypoint()) {
301 point_list.push_back(GetPointJsonFromLaneWaypoint(point));
303 drouting[
"point"] = point_list;
304 if (landmark.has_cycle_number()) {
305 drouting[
"cycleNumber"] = landmark.cycle_number();
308 default_routing_list.push_back(drouting);
310 response[
"data"][
"info"][
"code"] = 0;
311 response[
"data"][
"info"][
"message"] =
"Success";
315 "Failed to load default "
316 "routing. Please make sure the "
319 response[
"data"][
"info"][
"code"] = -1;
320 response[
"data"][
"info"][
"message"] =
321 "Failed to load default "
322 "routing. Please make sure the "
326 response[
"data"][
"info"][
"data"][
"defaultRoutings"] =
327 default_routing_list;
328 websocket_->
SendData(conn, response.dump());
332 "GetParkAndGoRoutings",
335 response[
"type"] =
"ParkAndGoRoutings";
336 Json park_go_routing_list = Json::array();
338 for (
const auto &landmark : park_go_routings_.landmark()) {
339 Json park_go_routing;
340 park_go_routing[
"name"] = landmark.name();
343 for (
const auto &point : landmark.waypoint()) {
344 point_list.push_back(GetPointJsonFromLaneWaypoint(point));
346 park_go_routing[
"point"] = point_list;
347 park_go_routing_list.push_back(park_go_routing);
357 response[
"parkAndGoRoutings"] = park_go_routing_list;
358 websocket_->
SendData(conn, response.dump());
362 "SaveDefaultRouting",
365 response[
"action"] =
"response";
366 std::string 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());
374 response[
"data"][
"requestId"] = request_id;
376 bool succeed = AddDefaultRouting(json);
380 if (!default_routing_) {
381 AERROR <<
"Failed to add a routing" << std::endl;
385 response[
"data"][
"info"][
"code"] = 0;
386 response[
"data"][
"info"][
"message"] =
"Success";
387 response[
"data"][
"info"][
"data"] = ret_data[
"data"];
390 "Failed to add a routing.");
391 response[
"data"][
"info"][
"code"] = -1;
392 response[
"data"][
"info"][
"message"] =
"Failed to add a routing";
394 websocket_->
SendData(conn, response.dump());
398 "DeleteDefaultRouting",
401 response[
"action"] =
"response";
402 std::string request_id, routing_name;
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());
410 response[
"data"][
"requestId"] = request_id;
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());
418 bool ret = DeleteDefaultRouting(routing_name);
420 response[
"data"][
"info"][
"code"] = -1;
421 response[
"data"][
"info"][
"message"] =
422 "Failed to delete default routing";
424 response[
"data"][
"info"][
"code"] = 0;
425 response[
"data"][
"info"][
"message"] =
"Success";
427 websocket_->
SendData(conn, response.dump());
431void SimulationWorldUpdater::RegisterMessageHandlers() {
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);
441 std::string retrieved_map_string;
442 retrieved.SerializeToString(&retrieved_map_string);
444 map_ws_->SendBinaryData(conn, retrieved_map_string, true);
446 AERROR <<
"Failed to parse MapElementIds from json";
451 map_ws_->RegisterMessageHandler(
452 "RetrieveRelativeMapData",
456 boost::shared_lock<boost::shared_mutex> reader_lock(mutex_);
457 to_send = relative_map_string_;
459 map_ws_->SendBinaryData(conn, to_send,
true);
462 websocket_->RegisterMessageHandler(
466 auto navigation_info = std::make_shared<NavigationInfo>();
467 if (navigation_info->ParseFromString(data)) {
468 sim_world_service_.PublishNavigationInfo(navigation_info);
470 AERROR <<
"Failed to parse navigation info from string. String size: "
475 websocket_->RegisterMessageHandler(
476 "RetrieveMapElementIdsByRadius",
478 auto radius = json.find(
"radius");
479 if (radius == json.end()) {
480 AERROR <<
"Cannot retrieve map elements with unknown radius.";
484 if (!radius->is_number()) {
485 AERROR <<
"Expect radius with type 'number', but was "
486 << radius->type_name();
491 response[
"type"] =
"MapElementIds";
492 response[
"mapRadius"] = *radius;
495 sim_world_service_.GetMapElementIds(*radius, &ids);
496 std::string elementIds;
497 MessageToJsonString(ids, &elementIds);
498 response[
"mapElementIds"] = Json::parse(elementIds);
500 websocket_->SendData(conn, response.dump());
503 websocket_->RegisterMessageHandler(
507 response[
"action"] =
"response";
508 std::string 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());
516 response[
"data"][
"requestId"] = request_id;
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"];
523 response[
"data"][
"info"][
"code"] = -1;
524 response[
"data"][
"info"][
"message"] = result[
"message"];
526 websocket_->SendData(conn, response.dump());
529 websocket_->RegisterMessageHandler(
533 std::string request_id;
534 response[
"action"] =
"response";
535 response[
"data"][
"info"] = {};
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());
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());
554 double x, y, heading;
555 std::vector<std::string> json_path = {
"data",
"info",
"point"};
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());
569 map_service_->GetPoseWithRegardToLane(x, y, &heading, &s);
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());
582 sim_control_manager->ReSetPoinstion(x, y, heading);
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);
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;
595 AERROR <<
"Failed to set start point to ascii file "
598 response[
"data"][
"info"][
"code"] = 0;
599 websocket_->SendData(conn, response.dump());
603 websocket_->RegisterMessageHandler(
607 std::string request_id;
608 response[
"action"] =
"response";
609 response[
"data"][
"info"] = {};
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());
617 response[
"data"][
"requestId"] = request_id;
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());
629 std::vector<std::string> json_path = {
"data",
"info",
"point"};
631 AERROR <<
"Miss point field to set start point,use map service to "
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());
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());
658 MapElementIds map_element_ids;
659 map_service_->CollectMapElementIds(point_enu, radius, &map_element_ids);
660 response[
"data"][
"info"][
"data"] =
662 response[
"data"][
"info"][
"code"] = 0;
663 websocket_->SendData(conn, response.dump());
667 websocket_->RegisterMessageHandler(
668 "GetMapElementsByIds",
671 std::string request_id;
672 response[
"action"] =
"response";
673 response[
"data"][
"info"] = {};
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());
681 response[
"data"][
"requestId"] = request_id;
682 Json element_ids_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());
691 MapElementIds map_element_ids;
692 if (!JsonStringToMessage(element_ids_json.dump(), &map_element_ids)
694 response[
"data"][
"info"][
"code"] = -1;
695 response[
"data"][
"info"][
"message"] =
696 "Failed to parse elementIds from json.";
697 websocket_->SendData(conn, response.dump());
700 auto retrieved = map_service_->RetrieveMapElements(map_element_ids);
704 response[
"data"][
"info"][
"code"] = 0;
705 websocket_->SendData(conn, response.dump());
709 websocket_->RegisterMessageHandler(
713 std::string request_id;
714 response[
"action"] =
"response";
715 response[
"data"][
"info"] = {};
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());
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());
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();
738 response[
"data"][
"info"][
"data"] = start_point;
739 websocket_->SendData(conn, response.dump());
743 websocket_->RegisterMessageHandler(
747 response[
"action"] =
"response";
748 std::string 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());
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());
817 websocket_->RegisterMessageHandler(
820 std::string 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());
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());
838 websocket_->RegisterMessageHandler(
841 std::string 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());
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());
858 websocket_->RegisterMessageHandler(
859 "GetParkingRoutingDistance",
862 response[
"type"] =
"ParkingRoutingDistance";
863 response[
"threshold"] = FLAGS_parking_routing_distance_threshold;
864 websocket_->SendData(conn, response.dump());
915 websocket_->RegisterMessageHandler(
918 Json response, result;
919 response[
"action"] =
"response";
920 std::string 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());
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"];
934 response[
"data"][
"info"][
"code"] = -1;
935 response[
"data"][
"info"][
"message"] = result[
"message"];
937 websocket_->SendData(conn, response.dump());
940 plugin_ws_->RegisterMessageHandler(
943 if (!plugin_manager_->IsEnabled()) {
946 auto iter = json.find(
"data");
947 if (iter == json.end()) {
948 AERROR <<
"Failed to get plugin msg!";
951 if (!plugin_manager_->SendMsgToPlugin(iter->dump())) {
952 AERROR <<
"Failed to send msg to plugin";
957bool SimulationWorldUpdater::CheckRoutingPoint(
const nlohmann::json &json,
958 nlohmann::json &result) {
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"];
967 if (!ValidateCoordinate(point) || !ContainsKey(point,
"id")) {
968 result[
"message"] =
"Failed to check routing point: invalid point.";
969 AERROR << result[
"message"];
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"];
981 if (!map_service_->CheckRoutingPointWithHeading(point[
"x"], point[
"y"],
983 result[
"pointId"] = point[
"id"];
984 result[
"isLegal"] = 0;
985 result[
"message"] =
"Selected point cannot be a routing point.";
986 AWARN << result[
"message"];
990 result[
"isLegal"] = 1;
991 result[
"message"] =
"Success";
995Json SimulationWorldUpdater::GetPointJsonFromLaneWaypoint(
998 point[
"x"] = waypoint.
pose().
x();
999 point[
"y"] = waypoint.
pose().
y();
1000 if (waypoint.has_heading()) {
1001 point[
"heading"] = waypoint.
heading();
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
1018 if (!map_service_->ConstructLaneWayPoint(point[
"x"], point[
"y"],
1020 AERROR <<
"Failed to prepare a routing request:"
1021 <<
" cannot locate " << description <<
" on map.";
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.";
1033 }
else if (!ContainsKey(json[
"data"],
"info")) {
1034 AERROR <<
"Failed to prepare a cycle lane follow command: info not found.";
1037 lane_follow_command->set_command_id(++command_id_);
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"]);
1051 if (!ContainsKey(json[
"data"][
"info"],
"end")) {
1052 AERROR <<
"Failed to prepare a routing request: end point not found.";
1056 auto end = json[
"data"][
"info"][
"end"];
1057 if (!ValidateCoordinate(end)) {
1058 AERROR <<
"Failed to prepare a routing request: invalid end point.";
1061 auto end_pose = lane_follow_command->mutable_end_pose();
1063 if (ContainsKey(end,
"heading")) {
1064 end_pose->set_heading(end[
"heading"]);
1066 end_pose->set_x(end[
"x"]);
1067 end_pose->set_y(end[
"y"]);
1069 AINFO <<
"Constructed LaneFollowCommand to be sent:\n"
1070 << lane_follow_command->DebugString();
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();
1086Json SimulationWorldUpdater::GetConstructRoutingRequestJson(
1087 const nlohmann::json &start,
const nlohmann::json &end) {
1089 result[
"start"] = start;
1090 result[
"end"] = end;
1094bool SimulationWorldUpdater::ValidateCoordinate(
const nlohmann::json &json) {
1095 if (!ContainsKey(json,
"x") || !ContainsKey(json,
"y")) {
1096 AERROR <<
"Failed to find x or y coordinate.";
1099 if (json.find(
"x")->is_number() && json.find(
"y")->is_number()) {
1102 AERROR <<
"Both x and y coordinate should be a number.";
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) {
1114 time_interval_ms, [
this]() { this->OnTimer(); },
false));
1121void SimulationWorldUpdater::StopStream(
const std::string &channel_name) {
1122 AINFO <<
"SimulationWorld updater has been stopped";
1128void SimulationWorldUpdater::OnTimer(
const std::string &channel_name) {
1129 sim_world_service_.Update();
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_);
1142void SimulationWorldUpdater::PublishMessage(
const std::string &channel_name) {
1143 if (!sim_world_service_.ReadyToPush()) {
1147 std::string to_send;
1149 boost::shared_lock<boost::shared_mutex> writer_lock(mutex_);
1150 to_send = simulation_world_with_planning_data_;
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);
1163bool SimulationWorldUpdater::LoadPOI() {
1164 if (GetProtoFromASCIIFile(EndWayPointFile(), &poi_)) {
1168 AWARN <<
"Failed to load default list of POI from " << EndWayPointFile();
1172bool SimulationWorldUpdater::LoadUserDefinedRoutings(
1173 const std::string &file_name, google::protobuf::Message *message) {
1175 if (GetProtoFromASCIIFile(file_name, message)) {
1179 AWARN <<
"Failed to load routings from " << file_name;
1183bool SimulationWorldUpdater::AddDefaultRouting(
const Json &json) {
1184 if (!ContainsKey(json,
"data")) {
1185 AERROR <<
"Failed to save a routing: data not found.";
1189 if (!ContainsKey(json[
"data"],
"info")) {
1190 AERROR <<
"Failed to save a routing: info not found.";
1194 if (!ContainsKey(json[
"data"][
"info"],
"name")) {
1195 AERROR <<
"Failed to save a routing: routing name not found.";
1199 if (!ContainsKey(json[
"data"][
"info"],
"point")) {
1200 AERROR <<
"Failed to save a routing: routing points not "
1205 if (!ContainsKey(json[
"data"][
"info"],
"routingType")) {
1206 AERROR <<
"Failed to save a routing: routing type not "
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.";
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"]);
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";
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"]));
1245 AINFO <<
"User Defined Routing Points to be saved:\n";
1246 std::string file_name =
1249 isDefaultRouting ? default_routings_ : park_go_routings_,
1251 AERROR <<
"Failed to set proto to ascii file " << file_name;
1254 AINFO <<
"Success in setting proto to file" << file_name;
1259bool SimulationWorldUpdater::DeleteDefaultRouting(
1260 const std::string &routing_name) {
1268 for (
auto &landmark : default_routings_.landmark()) {
1269 if (landmark.name() == routing_name) {
1272 ret_default_routings.add_landmark();
1273 ret_default_routings
1274 .mutable_landmark(ret_default_routings.landmark_size() - 1)
1275 ->CopyFrom(landmark);
1277 default_routings_.clear_landmark();
1278 default_routings_.mutable_landmark()->CopyFrom(
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";
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";
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;
1331 result[
"message"] =
"Unable to form a cycle routing";
1332 result[
"isCycle"] = 0;
1335 AERROR <<
"Failed to parse MapElementIds from json";
1336 result[
"message"] =
"Failed to parse MapElementIds from json";
static bool GetNumber(const nlohmann::json &json, const std::string &key, T *value)
Get a number value from the given json[key].
static bool GetStringByPath(const nlohmann::json &json, const std::string &path, std::string *value)
Get a string value from the given json and path.
static nlohmann::json ProtoToJson(const google::protobuf::Message &proto)
Convert proto to a json string.
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.
static nlohmann::json ProtoToTypedJson(const std::string &json_type, const google::protobuf::Message &proto)
Convert proto to a json string.
static bool GetNumberByPath(const nlohmann::json &json, const std::string &path, T *value)
Get a number value from the given json and path.
Used to perform oneshot or periodic timing tasks
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 AWARN_EVERY(freq)
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,...
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...
bool SetProtoToASCIIFile(const google::protobuf::Message &message, int file_descriptor)
std::string DefaultRoutingFile()
get default routing file path from flags.
std::string EndWayPointFile()
get end way point file path from flags.
std::string ParkGoRoutingFile()
get park and go routings file path from flags.
optional apollo::common::PointENU pose
repeated Landmark landmark