simulation_world_updater.cc 7.2 KB
Newer Older
S
siyangy 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

17
#include "modules/dreamview/backend/simulation_world/simulation_world_updater.h"
S
siyangy 已提交
18 19

#include "google/protobuf/util/json_util.h"
20
#include "modules/dreamview/backend/common/dreamview_gflags.h"
21
#include "modules/map/hdmap/hdmap_util.h"
S
siyangy 已提交
22 23 24 25

namespace apollo {
namespace dreamview {

S
siyangy 已提交
26
using apollo::common::adapter::AdapterManager;
27
using apollo::common::monitor::MonitorMessageItem;
28 29
using apollo::common::util::GetProtoFromASCIIFile;
using apollo::hdmap::EndWayPointFile;
30
using apollo::routing::RoutingRequest;
S
siyangy 已提交
31 32 33
using google::protobuf::util::MessageToJsonString;
using Json = nlohmann::json;

34
SimulationWorldUpdater::SimulationWorldUpdater(WebSocketHandler *websocket,
35
                                               const MapService *map_service,
S
siyangy 已提交
36 37
                                               bool routing_from_file)
    : sim_world_service_(map_service, routing_from_file),
38
      map_service_(map_service),
S
siyangy 已提交
39
      websocket_(websocket) {
40
  // Initialize default end point
41 42 43
  if (!GetProtoFromASCIIFile(EndWayPointFile(), &default_end_point_)) {
    AWARN << "Failed to load default end point from " << EndWayPointFile();
  }
44

S
siyangy 已提交
45 46 47 48 49 50
  websocket_->RegisterMessageHandler(
      "RetrieveMapData",
      [this](const Json &json, WebSocketHandler::Connection *conn) {
        auto iter = json.find("elements");
        if (iter != json.end()) {
          MapElementIds map_element_ids(*iter);
51
          auto retrieved = map_service_->RetrieveMapElements(map_element_ids);
S
siyangy 已提交
52 53 54 55 56 57 58 59

          std::string retrieved_json_string;
          MessageToJsonString(retrieved, &retrieved_json_string);

          Json response;
          response["type"] = "MapData";
          response["data"] = Json::parse(retrieved_json_string);

60
          websocket_->SendData(conn, response.dump());
S
siyangy 已提交
61 62
        }
      });
63

64
  websocket_->RegisterMessageHandler(
65
      "RetrieveMapElementsByRadius",
66 67 68
      [this](const Json &json, WebSocketHandler::Connection *conn) {
        auto radius = json.find("radius");
        if (radius == json.end()) {
69
          AERROR << "Cannot retrieve map elements with unknown radius.";
70
          return;
71 72
        }

73 74
        Json response = sim_world_service_.GetMapElements(*radius);
        response["type"] = "MapElements";
75
        websocket_->SendData(conn, response.dump());
76 77
      });

78 79 80
  websocket_->RegisterMessageHandler(
      "SendRoutingRequest",
      [this](const Json &json, WebSocketHandler::Connection *conn) {
81
        RoutingRequest routing_request;
82

83 84 85 86 87 88 89
        bool succeed = ConstructRoutingRequest(json, &routing_request);
        if (succeed) {
          AdapterManager::FillRoutingRequestHeader(FLAGS_dreamview_module_name,
                                                   &routing_request);
          AdapterManager::PublishRoutingRequest(routing_request);
        }

90
        // Publish monitor message.
91
        if (succeed) {
92 93
          sim_world_service_.PublishMonitorMessage(MonitorMessageItem::INFO,
                                                   "Routing Request Sent");
94
        } else {
S
siyangy 已提交
95 96
          sim_world_service_.PublishMonitorMessage(
              MonitorMessageItem::ERROR, "Failed to send routing request");
97
        }
98
      });
99 100

  websocket_->RegisterMessageHandler(
101 102
      "RequestSimulationWorld",
      [this](const Json &json, WebSocketHandler::Connection *conn) {
103 104 105 106 107 108
        if (!sim_world_service_.ReadyToPush()) {
          AWARN_EVERY(100)
              << "Not sending simulation world as the data is not ready!";
          return;
        }

109 110 111 112 113 114 115
        std::string to_send;
        {
          // Pay the price to copy the data instead of sending data over the
          // wire while holding the lock.
          boost::shared_lock<boost::shared_mutex> reader_lock(mutex_);
          to_send = simulation_world_json_;
        }
116
        websocket_->SendData(conn, to_send, true);
117
      });
118 119 120
}

bool SimulationWorldUpdater::ConstructRoutingRequest(
S
siyangy 已提交
121
    const Json &json, RoutingRequest *routing_request) {
122 123 124 125 126 127 128
  // Input validations
  if (json.find("start") == json.end() ||
      json.find("sendDefaultRoute") == json.end()) {
    AERROR << "Cannot prepare a routing request: input validation failed.";
    return false;
  }

129 130 131
  // set start point
  auto start = json["start"];
  if (start.find("x") == start.end() || start.find("y") == start.end()) {
132
    AERROR << "Failed to prepare a routing request: start point not found";
133 134 135 136 137 138 139 140
    return false;
  }
  map_service_->ConstructLaneWayPoint(start["x"], start["y"],
                                      routing_request->mutable_start());

  // set way point(s) if any
  auto iter = json.find("waypoint");
  if (iter != json.end()) {
S
siyangy 已提交
141
    auto *waypoint = routing_request->mutable_waypoint();
142
    for (size_t i = 0; i < iter->size(); ++i) {
S
siyangy 已提交
143
      auto &point = (*iter)[i];
144 145 146 147 148 149 150 151
      if (!map_service_->ConstructLaneWayPoint(point["x"], point["y"],
                                               waypoint->Add())) {
        waypoint->RemoveLast();
      }
    }
  }

  // set end point
152 153
  RoutingRequest::LaneWaypoint *endLane = routing_request->mutable_end();
  if (json["sendDefaultRoute"]) {
154 155 156 157 158 159 160
    // Try to reload end point if it hasn't been loaded yet.
    if (!default_end_point_.has_id() &&
        !GetProtoFromASCIIFile(EndWayPointFile(), &default_end_point_)) {
      AERROR << "Failed to load default end point from " << EndWayPointFile();
      return false;
    }

161 162 163 164 165 166
    endLane->set_id(default_end_point_.id());
    endLane->set_s(default_end_point_.s());
    auto *pose = endLane->mutable_pose();
    pose->set_x(default_end_point_.pose().x());
    pose->set_y(default_end_point_.pose().y());
  } else {
167 168 169 170 171
    if (json.find("end") == json.end()) {
      AERROR << "Failed to prepare a routing request: end point not found";
      return false;
    }

172 173 174 175 176 177
    auto end = json["end"];
    if (end.find("x") == end.end() || end.find("y") == end.end()) {
      AERROR << "Failed to prepare a routing request: end point not found";
      return false;
    }
    map_service_->ConstructLaneWayPoint(end["x"], end["y"], endLane);
178 179 180
  }

  return true;
S
siyangy 已提交
181 182
}

S
siyangy 已提交
183 184
void SimulationWorldUpdater::Start() {
  // start ROS timer, one-shot = false, auto-start = true
185 186
  timer_ = AdapterManager::CreateTimer(ros::Duration(kSimWorldTimeInterval),
                                       &SimulationWorldUpdater::OnTimer, this);
S
siyangy 已提交
187 188
}

189
void SimulationWorldUpdater::OnTimer(const ros::TimerEvent &event) {
S
siyangy 已提交
190
  sim_world_service_.Update();
191 192 193 194 195

  {
    boost::unique_lock<boost::shared_mutex> writer_lock(mutex_);

    simulation_world_json_ =
196
        sim_world_service_.GetUpdateAsJson(FLAGS_map_radius).dump();
197
  }
S
siyangy 已提交
198 199 200 201
}

}  // namespace dreamview
}  // namespace apollo