simulation_world_updater.cc 7.9 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,
S
siyangy 已提交
35
                                               SimControl *sim_control,
36
                                               const MapService *map_service,
S
siyangy 已提交
37 38
                                               bool routing_from_file)
    : sim_world_service_(map_service, routing_from_file),
39
      map_service_(map_service),
S
siyangy 已提交
40 41
      websocket_(websocket),
      sim_control_(sim_control) {
42
  // Initialize default end point
43
  LoadDefaultEndPoint();
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 121 122 123 124 125 126 127 128 129 130

  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 已提交
131 132 133 134

  websocket_->RegisterMessageHandler(
      "Reset", [this](const Json &json, WebSocketHandler::Connection *conn) {
        sim_world_service_.SetToClear();
S
siyangy 已提交
135
        sim_control_->ClearPlanning();
S
siyangy 已提交
136
      });
137 138 139
}

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

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

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

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

185 186 187 188 189
    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 已提交
190
    map_service_->ConstructLaneWayPoint(end["x"], end["y"], end_point);
191 192
  }

S
siyangy 已提交
193 194
  AINFO << "Constructed RoutingRequest to be sent, waypoints: "
        << routing_request->DebugString();
195

196
  return true;
S
siyangy 已提交
197 198
}

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

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

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

    simulation_world_json_ =
212
        sim_world_service_.GetUpdateAsJson(FLAGS_map_radius).dump();
213
  }
S
siyangy 已提交
214 215
}

216 217 218 219 220 221 222 223 224 225 226 227
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 已提交
228 229
}  // namespace dreamview
}  // namespace apollo