simulation_world_updater.cc 7.7 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
  LoadDefaultEndPoint();
42

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

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

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

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

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

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

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

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

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

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

107 108 109 110 111 112 113
        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_;
        }
114
        websocket_->SendData(conn, to_send, true);
115
      });
116 117 118 119 120 121 122 123 124 125 126 127 128

  websocket_->RegisterMessageHandler(
      "GetDefaultEndPoint",
      [this](const Json &json, WebSocketHandler::Connection *conn) {
        Json response;
        response["type"] = "DefaultEndPoint";

        if (LoadDefaultEndPoint()) {
          response["end_x"] = default_end_point_.pose().x();
          response["end_y"] = default_end_point_.pose().y();
        }
        websocket_->SendData(conn, response.dump());
      });
S
siyangy 已提交
129 130 131 132 133

  websocket_->RegisterMessageHandler(
      "Reset", [this](const Json &json, WebSocketHandler::Connection *conn) {
        sim_world_service_.SetToClear();
      });
134 135 136
}

bool SimulationWorldUpdater::ConstructRoutingRequest(
S
siyangy 已提交
137
    const Json &json, RoutingRequest *routing_request) {
138 139 140 141 142 143 144
  // Input validations
  if (json.find("start") == json.end() ||
      json.find("sendDefaultRoute") == json.end()) {
    AERROR << "Cannot prepare a routing request: input validation failed.";
    return false;
  }

145 146 147
  // set start point
  auto start = json["start"];
  if (start.find("x") == start.end() || start.find("y") == start.end()) {
148
    AERROR << "Failed to prepare a routing request: start point not found";
149 150
    return false;
  }
151
  routing_request->clear_waypoint();
152
  map_service_->ConstructLaneWayPoint(start["x"], start["y"],
153
                                      routing_request->add_waypoint());
154 155 156 157

  // set way point(s) if any
  auto iter = json.find("waypoint");
  if (iter != json.end()) {
S
siyangy 已提交
158
    auto *waypoint = routing_request->mutable_waypoint();
159
    for (size_t i = 0; i < iter->size(); ++i) {
S
siyangy 已提交
160
      auto &point = (*iter)[i];
161 162 163 164 165 166 167 168
      if (!map_service_->ConstructLaneWayPoint(point["x"], point["y"],
                                               waypoint->Add())) {
        waypoint->RemoveLast();
      }
    }
  }

  // set end point
S
siyangy 已提交
169
  auto *end_point = routing_request->add_waypoint();
170
  if (json["sendDefaultRoute"]) {
171
    // Try to reload end point if it hasn't been loaded yet.
172
    if (!LoadDefaultEndPoint()) {
173 174
      return false;
    }
S
siyangy 已提交
175
    end_point->CopyFrom(default_end_point_);
176
  } else {
177 178 179 180 181
    if (json.find("end") == json.end()) {
      AERROR << "Failed to prepare a routing request: end point not found";
      return false;
    }

182 183 184 185 186
    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;
    }
S
siyangy 已提交
187
    map_service_->ConstructLaneWayPoint(end["x"], end["y"], end_point);
188 189
  }

S
siyangy 已提交
190 191
  AINFO << "Constructed RoutingRequest to be sent, waypoints: "
        << routing_request->DebugString();
192

193
  return true;
S
siyangy 已提交
194 195
}

S
siyangy 已提交
196 197
void SimulationWorldUpdater::Start() {
  // start ROS timer, one-shot = false, auto-start = true
198 199
  timer_ = AdapterManager::CreateTimer(ros::Duration(kSimWorldTimeInterval),
                                       &SimulationWorldUpdater::OnTimer, this);
S
siyangy 已提交
200 201
}

202
void SimulationWorldUpdater::OnTimer(const ros::TimerEvent &event) {
S
siyangy 已提交
203
  sim_world_service_.Update();
204 205 206 207 208

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

    simulation_world_json_ =
209
        sim_world_service_.GetUpdateAsJson(FLAGS_map_radius).dump();
210
  }
S
siyangy 已提交
211 212
}

213 214 215 216 217 218 219 220 221 222 223 224
bool SimulationWorldUpdater::LoadDefaultEndPoint() {
  bool ret =
      default_end_point_.has_id()
          ? true
          : GetProtoFromASCIIFile(EndWayPointFile(), &default_end_point_);

  if (!ret) {
    AWARN << "Failed to load default end point from " << EndWayPointFile();
  }
  return ret;
}

S
siyangy 已提交
225 226
}  // namespace dreamview
}  // namespace apollo