19#include <unordered_set>
21#include "absl/strings/str_split.h"
22#include "google/protobuf/util/json_util.h"
24#include "modules/common_msgs/basic_msgs/geometry.pb.h"
25#include "modules/common_msgs/basic_msgs/vehicle_signal.pb.h"
26#include "modules/common_msgs/chassis_msgs/chassis.pb.h"
27#include "modules/common_msgs/dreamview_msgs/simulation_world.pb.h"
54using apollo::common::util::FillHeader;
75using apollo::planning::DecisionResult;
76using apollo::planning::StopReasonCode;
89using Json = nlohmann::json;
90using ::google::protobuf::util::MessageToJsonString;
93static constexpr double kAngleThreshold = 0.1;
97std::map<int, std::string> ScenarioType = {
99 {2,
"BARE_INTERSECTION_UNPROTECTED"},
100 {3,
"STOP_SIGN_PROTECTED"},
101 {4,
"TRAFFIC_LIGHT_PROTECTED"},
102 {5,
"TRAFFIC_LIGHT_PROTECTED"},
103 {6,
"TRAFFIC_LIGHT_UNPROTECTED_LEFT_TURN"},
104 {7,
"TRAFFIC_LIGHT_UNPROTECTED_RIGHT_TURN"},
107 {10,
"VALET_PARKING"},
108 {11,
"EMERGENCY_PULL_OVER"},
109 {12,
"EMERGENCY_STOP"},
110 {13,
"NARROW_STREET_U_TURN"},
112 {15,
"LEARNING_MODEL_SAMPLE"},
113 {16,
"DEADEND_TURNAROUND"}};
115std::map<int, std::string> StageType = {
117 {1,
"LANE_FOLLOW_DEFAULT_STAGE"},
118 {200,
"BARE_INTERSECTION_UNPROTECTED_APPROACH"},
119 {201,
"BARE_INTERSECTION_UNPROTECTED_INTERSECTION_CRUISE"},
120 {300,
"STOP_SIGN_UNPROTECTED_PRE_STOP"},
121 {301,
"STOP_SIGN_UNPROTECTED_STOP"},
122 {302,
"STOP_SIGN_UNPROTECTED_CREEP"},
123 {303,
"STOP_SIGN_UNPROTECTED_INTERSECTION_CRUISE"},
124 {400,
"TRAFFIC_LIGHT_PROTECTED_APPROACH"},
125 {401,
"TRAFFIC_LIGHT_PROTECTED_INTERSECTION_CRUISE"},
126 {410,
"TRAFFIC_LIGHT_UNPROTECTED_LEFT_TURN_APPROACH"},
127 {411,
"TRAFFIC_LIGHT_UNPROTECTED_LEFT_TURN_CREEP"},
128 {412,
"TRAFFIC_LIGHT_UNPROTECTED_LEFT_TURN_INTERSECTION_CRUISE"},
129 {420,
"TRAFFIC_LIGHT_UNPROTECTED_RIGHT_TURN_STOP"},
130 {421,
"TRAFFIC_LIGHT_UNPROTECTED_RIGHT_TURN_CREEP"},
131 {422,
"TRAFFIC_LIGHT_UNPROTECTED_RIGHT_TURN_INTERSECTION_CRUISE"},
132 {500,
"PULL_OVER_APPROACH"},
133 {501,
"PULL_OVER_RETRY_APPROACH_PARKING"},
134 {502,
"PULL_OVER_RETRY_PARKING"},
135 {600,
"EMERGENCY_PULL_OVER_SLOW_DOWN"},
136 {601,
"EMERGENCY_PULL_OVER_APPROACH"},
137 {602,
"EMERGENCY_PULL_OVER_STANDBY"},
138 {610,
"EMERGENCY_STOP_APPROACH"},
139 {611,
"EMERGENCY_STOP_STANDBY"},
140 {700,
"VALET_PARKING_APPROACHING_PARKING_SPOT"},
141 {701,
"VALET_PARKING_PARKING"},
142 {1100,
"DEADEND_TURNAROUND_APPROACHING_TURNING_POINT"},
143 {1101,
"DEADEND_TURNAROUND_TURNING"},
144 {800,
"PARK_AND_GO_CHECK"},
145 {801,
"PARK_AND_GO_CRUISE"},
146 {802,
"PARK_AND_GO_ADJUST"},
147 {803,
"PARK_AND_GO_PRE_CRUISE"},
148 {900,
"YIELD_SIGN_APPROACH"},
149 {901,
"YIELD_SIGN_CREEP"},
150 {1000,
"LEARNING_MODEL_RUN"}};
152double CalculateAcceleration(
153 const Point3D &acceleration,
const Point3D &velocity,
154 const apollo::canbus::Chassis_GearPosition &gear_location) {
159 acceleration.x() * velocity.x() + acceleration.y() * velocity.y();
163 double magnitude = std::hypot(acceleration.x(), acceleration.y());
164 if (std::signbit(projection)) {
165 magnitude = -magnitude;
170 magnitude = -magnitude;
181 switch (chassis.driving_mode()) {
199 Object *world_object) {
200 if (world_object ==
nullptr) {
204 switch (obstacle_type) {
206 world_object->set_type(Object_Type_UNKNOWN);
209 world_object->set_type(Object_Type_UNKNOWN_MOVABLE);
212 world_object->set_type(Object_Type_UNKNOWN_UNMOVABLE);
215 world_object->set_type(Object_Type_PEDESTRIAN);
218 world_object->set_type(Object_Type_BICYCLE);
221 world_object->set_type(Object_Type_VEHICLE);
224 world_object->set_type(Object_Type_VIRTUAL);
227 world_object->set_sub_type(obstacle_subtype);
230void SetStopReason(
const StopReasonCode &reason_code, Decision *decision) {
231 switch (reason_code) {
232 case StopReasonCode::STOP_REASON_HEAD_VEHICLE:
235 case StopReasonCode::STOP_REASON_DESTINATION:
238 case StopReasonCode::STOP_REASON_PEDESTRIAN:
241 case StopReasonCode::STOP_REASON_OBSTACLE:
244 case StopReasonCode::STOP_REASON_SIGNAL:
247 case StopReasonCode::STOP_REASON_STOP_SIGN:
250 case StopReasonCode::STOP_REASON_YIELD_SIGN:
253 case StopReasonCode::STOP_REASON_CLEAR_ZONE:
256 case StopReasonCode::STOP_REASON_CROSSWALK:
259 case StopReasonCode::STOP_REASON_PULL_OVER:
263 AWARN <<
"Unrecognizable stop reason code:" << reason_code;
268 Object *auto_driving_car) {
270 auto_driving_car->set_current_signal(
"LEFT");
273 auto_driving_car->set_current_signal(
"RIGHT");
275 auto_driving_car->set_current_signal(
"EMERGENCY");
277 auto_driving_car->set_current_signal(
"");
281void DownsampleCurve(Curve *curve) {
282 if (curve->segment().empty()) {
286 auto *line_segment = curve->mutable_segment(0)->mutable_line_segment();
287 std::vector<PointENU> points(line_segment->point().begin(),
288 line_segment->point().end());
289 line_segment->clear_point();
292 std::vector<size_t> sampled_indices =
294 for (
const size_t index : sampled_indices) {
295 *line_segment->add_point() = points[index];
299inline double SecToMs(
const double sec) {
return sec * 1000.0; }
304bool SimulationWorldService::to_clear_ =
false;
306 bool routing_from_file)
307 : node_(cyber::
CreateNode(
"simulation_world")),
308 map_service_(map_service),
309 monitor_logger_buffer_(MonitorMessageItem::SIMULATOR),
310 ready_to_push_(false) {
314 if (routing_from_file) {
315 ReadPlanningCommandFromFile(FLAGS_routing_response_file);
319 Object *auto_driving_car = world_.mutable_auto_driving_car();
320 const auto &vehicle_param = VehicleConfigHelper::GetConfig().vehicle_param();
321 auto_driving_car->set_height(vehicle_param.height());
322 auto_driving_car->set_width(vehicle_param.width());
323 auto_driving_car->set_length(vehicle_param.length());
326void SimulationWorldService::InitReaders() {
327 planning_command_reader_ =
328 node_->CreateReader<PlanningCommand>(FLAGS_planning_command);
329 chassis_reader_ = node_->CreateReader<Chassis>(FLAGS_chassis_topic);
330 gps_reader_ = node_->CreateReader<Gps>(FLAGS_gps_topic);
331 localization_reader_ =
332 node_->CreateReader<LocalizationEstimate>(FLAGS_localization_topic);
333 perception_obstacle_reader_ =
334 node_->CreateReader<PerceptionObstacles>(FLAGS_perception_obstacle_topic);
335 perception_traffic_light_reader_ = node_->CreateReader<TrafficLightDetection>(
336 FLAGS_traffic_light_detection_topic);
337 prediction_obstacle_reader_ =
338 node_->CreateReader<PredictionObstacles>(FLAGS_prediction_topic);
340 node_->CreateReader<ADCTrajectory>(FLAGS_planning_trajectory_topic);
341 control_command_reader_ =
342 node_->CreateReader<ControlCommand>(FLAGS_control_command_topic);
344 node_->CreateReader<NavigationInfo>(FLAGS_navigation_topic);
345 relative_map_reader_ = node_->CreateReader<MapMsg>(FLAGS_relative_map_topic);
346 storytelling_reader_ = node_->CreateReader<Stories>(FLAGS_storytelling_topic);
347 audio_detection_reader_ =
348 node_->CreateReader<AudioDetection>(FLAGS_audio_detection_topic);
350 audio_event_reader_ = node_->CreateReader<AudioEvent>(
351 FLAGS_audio_event_topic,
352 [
this](
const std::shared_ptr<AudioEvent> &audio_event) {
353 this->PublishMonitorMessage(
354 MonitorMessageItem::WARN,
355 apollo::audio::AudioType_Name(audio_event->audio_type()));
357 drive_event_reader_ = node_->CreateReader<DriveEvent>(
358 FLAGS_drive_event_topic,
359 [
this](
const std::shared_ptr<DriveEvent> &drive_event) {
360 this->PublishMonitorMessage(MonitorMessageItem::WARN,
361 drive_event->event());
363 cyber::ReaderConfig monitor_message_reader_config;
364 monitor_message_reader_config.channel_name = FLAGS_monitor_topic;
365 monitor_message_reader_config.pending_queue_size =
366 FLAGS_monitor_msg_pending_queue_size;
367 monitor_reader_ = node_->CreateReader<MonitorMessage>(
368 monitor_message_reader_config,
369 [
this](
const std::shared_ptr<MonitorMessage> &monitor_message) {
370 std::unique_lock<std::mutex> lock(monitor_msgs_mutex_);
371 monitor_msgs_.push_back(monitor_message);
373 task_reader_ = node_->CreateReader<Task>(FLAGS_task_topic);
376void SimulationWorldService::InitWriters() {
378 node_->CreateWriter<NavigationInfo>(FLAGS_navigation_topic);
379 lane_follow_command_client_ =
380 node_->CreateClient<LaneFollowCommand, CommandStatus>(
381 FLAGS_lane_follow_command_topic);
382 valet_parking_command_client_ =
383 node_->CreateClient<ValetParkingCommand, CommandStatus>(
384 FLAGS_valet_parking_command_topic);
385 action_command_client_ =
386 node_->CreateClient<ActionCommand, CommandStatus>(
387 FLAGS_action_command_topic);
388 routing_response_writer_ =
389 node_->CreateWriter<RoutingResponse>(
"/apollo/routing_response");
390 task_writer_ = node_->CreateWriter<Task>(FLAGS_task_topic);
393void SimulationWorldService::Update() {
399 auto car = world_.auto_driving_car();
401 *world_.mutable_auto_driving_car() = car;
404 boost::unique_lock<boost::shared_mutex> writer_lock(route_paths_mutex_);
405 route_paths_.clear();
413 UpdateMonitorMessages();
415 UpdateVehicleParam();
417 UpdateWithLatestObserved(planning_command_reader_.get(),
false);
418 UpdateWithLatestObserved(chassis_reader_.get());
419 UpdateWithLatestObserved(gps_reader_.get());
420 UpdateWithLatestObserved(localization_reader_.get());
427 world_.clear_object();
428 world_.clear_sensor_measurements();
429 UpdateWithLatestObserved(audio_detection_reader_.get());
430 UpdateWithLatestObserved(storytelling_reader_.get());
431 UpdateWithLatestObserved(perception_obstacle_reader_.get());
432 UpdateWithLatestObserved(perception_traffic_light_reader_.get(),
false);
433 UpdateWithLatestObserved(prediction_obstacle_reader_.get());
434 UpdateWithLatestObserved(planning_reader_.get());
435 UpdateWithLatestObserved(control_command_reader_.get());
436 UpdateWithLatestObserved(navigation_reader_.get(), FLAGS_use_navigation_mode);
437 UpdateWithLatestObserved(relative_map_reader_.get(),
438 FLAGS_use_navigation_mode);
440 for (
const auto &kv : obj_map_) {
441 *world_.add_object() = kv.second;
447 world_.set_sequence_num(world_.sequence_num() + 1);
448 world_.set_timestamp(
Clock::Now().ToSecond() * 1000);
451void SimulationWorldService::UpdateDelays() {
452 auto *delays = world_.mutable_delay();
453 delays->set_chassis(SecToMs(chassis_reader_->GetDelaySec()));
454 delays->set_localization(SecToMs(localization_reader_->GetDelaySec()));
455 delays->set_perception_obstacle(
456 SecToMs(perception_obstacle_reader_->GetDelaySec()));
457 delays->set_planning(SecToMs(planning_reader_->GetDelaySec()));
458 delays->set_prediction(SecToMs(prediction_obstacle_reader_->GetDelaySec()));
459 delays->set_traffic_light(
460 SecToMs(perception_traffic_light_reader_->GetDelaySec()));
461 delays->set_control(SecToMs(control_command_reader_->GetDelaySec()));
464void SimulationWorldService::UpdateLatencies() {
465 UpdateLatency(
"chassis", chassis_reader_.get());
466 UpdateLatency(
"localization", localization_reader_.get());
467 UpdateLatency(
"perception", perception_obstacle_reader_.get());
468 UpdateLatency(
"planning", planning_reader_.get());
469 UpdateLatency(
"prediction", prediction_obstacle_reader_.get());
470 UpdateLatency(
"control", control_command_reader_.get());
473void SimulationWorldService::GetWireFormatString(
474 double radius, std::string *sim_world_with_planning_data) {
475 PopulateMapInfo(radius);
477 world_.SerializeToString(sim_world_with_planning_data);
480Json SimulationWorldService::GetUpdateAsJson(
double radius)
const {
481 std::string sim_world_json_string;
482 MessageToJsonString(world_, &sim_world_json_string);
485 update[
"type"] =
"SimWorldUpdate";
487 update[
"world"] = sim_world_json_string;
492void SimulationWorldService::GetMapElementIds(
double radius,
493 MapElementIds *ids)
const {
496 const auto &adc = world_.auto_driving_car();
497 point.set_x(adc.position_x());
498 point.set_y(adc.position_y());
499 map_service_->CollectMapElementIds(point, radius, ids);
502void SimulationWorldService::PopulateMapInfo(
double radius) {
503 world_.clear_map_element_ids();
504 GetMapElementIds(radius, world_.mutable_map_element_ids());
505 world_.set_map_hash(map_service_->CalculateMapHash(world_.map_element_ids()));
506 world_.set_map_radius(radius);
509const Map &SimulationWorldService::GetRelativeMap()
const {
510 return relative_map_;
514void SimulationWorldService::UpdateSimulationWorld(
516 Object *auto_driving_car = world_.mutable_auto_driving_car();
517 const auto &pose = localization.
pose();
520 auto_driving_car->set_position_x(pose.position().x() +
521 map_service_->GetXOffset());
522 auto_driving_car->set_position_y(pose.position().y() +
523 map_service_->GetYOffset());
524 auto_driving_car->set_heading(pose.heading());
527 auto_driving_car->set_speed_acceleration(CalculateAcceleration(
528 pose.linear_acceleration(), pose.linear_velocity(), gear_location_));
534 ready_to_push_.store(
true);
538void SimulationWorldService::UpdateSimulationWorld(
const Gps &gps) {
540 Object *shadow_localization_position = world_.mutable_shadow_localization();
542 shadow_localization_position->set_position_x(pose.position().x() +
543 map_service_->GetXOffset());
544 shadow_localization_position->set_position_y(pose.position().y() +
545 map_service_->GetYOffset());
546 shadow_localization_position->set_heading(pose.heading());
548 Object *gps_position = world_.mutable_gps();
552 gps_position->set_position_x(pose.position().x() +
553 map_service_->GetXOffset());
554 gps_position->set_position_y(pose.position().y() +
555 map_service_->GetYOffset());
558 pose.orientation().qw(), pose.orientation().qx(),
559 pose.orientation().qy(), pose.orientation().qz());
560 gps_position->set_heading(heading);
565void SimulationWorldService::UpdateSimulationWorld(
const Chassis &chassis) {
566 const auto &vehicle_param = VehicleConfigHelper::GetConfig().vehicle_param();
567 Object *auto_driving_car = world_.mutable_auto_driving_car();
571 if (gear_location_ == Chassis::GEAR_REVERSE) {
574 auto_driving_car->set_speed(speed);
580 if (angle_percentage > 100 || angle_percentage < -100) {
581 angle_percentage = 0;
583 auto_driving_car->set_steering_percentage(angle_percentage);
585 double steering_angle =
586 angle_percentage / 100.0 * vehicle_param.max_steer_angle();
587 auto_driving_car->set_steering_angle(steering_angle);
589 double kappa = std::tan(steering_angle / vehicle_param.steer_ratio()) /
590 vehicle_param.wheel_base();
591 auto_driving_car->set_kappa(kappa);
593 UpdateTurnSignal(chassis.
signal(), auto_driving_car);
595 auto_driving_car->set_disengage_type(DeduceDisengageType(chassis));
598 auto_driving_car->set_gear_location(chassis.
gear_location());
602void SimulationWorldService::UpdateSimulationWorld(
const Stories &stories) {
603 world_.clear_stories();
604 auto *world_stories = world_.mutable_stories();
606 const google::protobuf::Descriptor *descriptor = stories.GetDescriptor();
607 const google::protobuf::Reflection *reflection = stories.GetReflection();
608 const int field_count = descriptor->field_count();
609 for (
int i = 0; i < field_count; ++i) {
610 const google::protobuf::FieldDescriptor *field = descriptor->field(i);
611 if (field->name() !=
"header") {
612 (*world_stories)[field->name()] = reflection->HasField(stories, field);
618void SimulationWorldService::UpdateSimulationWorld(
620 world_.set_is_siren_on(audio_detection.
is_siren());
623Object &SimulationWorldService::CreateWorldObjectIfAbsent(
625 const std::string
id = std::to_string(obstacle.
id());
628 if (!apollo::common::util::ContainsKey(obj_map_,
id)) {
629 Object &world_obj = obj_map_[id];
630 SetObstacleInfo(obstacle, &world_obj);
631 SetObstaclePolygon(obstacle, &world_obj);
632 SetObstacleType(obstacle.
type(), obstacle.
sub_type(), &world_obj);
633 SetObstacleSensorMeasurements(obstacle, &world_obj);
634 SetObstacleSource(obstacle, &world_obj);
639void SimulationWorldService::CreateWorldObjectFromSensorMeasurement(
640 const SensorMeasurement &sensor, Object *world_object) {
641 world_object->set_id(std::to_string(sensor.id()));
642 world_object->set_position_x(sensor.position().x());
643 world_object->set_position_y(sensor.position().y());
644 world_object->set_heading(sensor.theta());
645 world_object->set_length(sensor.length());
646 world_object->set_width(sensor.width());
647 world_object->set_height(sensor.height());
648 SetObstacleType(sensor.type(), sensor.sub_type(), world_object);
651void SimulationWorldService::SetObstacleInfo(
const PerceptionObstacle &obstacle,
652 Object *world_object) {
653 if (world_object ==
nullptr) {
657 world_object->set_id(std::to_string(obstacle.id()));
658 world_object->set_position_x(obstacle.position().x() +
659 map_service_->GetXOffset());
660 world_object->set_position_y(obstacle.position().y() +
661 map_service_->GetYOffset());
662 world_object->set_heading(obstacle.theta());
663 world_object->set_length(obstacle.length());
664 world_object->set_width(obstacle.width());
665 world_object->set_height(obstacle.height());
666 world_object->set_speed(
667 std::hypot(obstacle.velocity().x(), obstacle.velocity().y()));
668 world_object->set_speed_heading(
669 std::atan2(obstacle.velocity().y(), obstacle.velocity().x()));
670 world_object->set_timestamp_sec(obstacle.timestamp());
671 world_object->set_confidence(obstacle.has_confidence() ? obstacle.confidence()
675void SimulationWorldService::SetObstaclePolygon(
676 const PerceptionObstacle &obstacle, Object *world_object) {
677 if (world_object ==
nullptr) {
682 std::unordered_set<std::pair<double, double>, PairHash> seen_points;
683 world_object->clear_polygon_point();
684 for (
const auto &point : obstacle.polygon_point()) {
686 std::pair<double, double> xy_pair = {point.
x(), point.
y()};
687 if (seen_points.count(xy_pair) == 0) {
688 PolygonPoint *poly_pt = world_object->add_polygon_point();
689 poly_pt->set_x(point.
x() + map_service_->GetXOffset());
690 poly_pt->set_y(point.
y() + map_service_->GetYOffset());
691 seen_points.insert(xy_pair);
696void SimulationWorldService::SetObstacleSensorMeasurements(
697 const PerceptionObstacle &obstacle, Object *world_object) {
698 if (world_object ==
nullptr) {
701 for (
const auto &sensor : obstacle.measurements()) {
702 Object *obj = (*(world_.mutable_sensor_measurements()))[sensor.sensor_id()]
703 .add_sensor_measurement();
704 CreateWorldObjectFromSensorMeasurement(sensor, obj);
708void SimulationWorldService::SetObstacleSource(
710 Object *world_object) {
711 if (world_object ==
nullptr || !obstacle.has_source()) {
714 const PerceptionObstacle::Source obstacle_source = obstacle.
source();
715 world_object->set_source(obstacle_source);
716 world_object->clear_v2x_info();
717 if (obstacle_source == PerceptionObstacle::V2X && obstacle.has_v2x_info()) {
718 world_object->mutable_v2x_info()->CopyFrom(obstacle.
v2x_info());
724void SimulationWorldService::UpdateSimulationWorld(
727 auto &world_obj = CreateWorldObjectIfAbsent(obstacle);
728 if (obstacles.has_cipv_info() &&
730 world_obj.set_type(Object_Type_CIPV);
734 if (obstacles.has_lane_marker()) {
735 world_.mutable_lane_marker()->CopyFrom(obstacles.
lane_marker());
740void SimulationWorldService::UpdateSimulationWorld(
742 world_.clear_perceived_signal();
743 for (
const auto &traffic_light : traffic_light_detection.
traffic_light()) {
744 Object *signal = world_.add_perceived_signal();
745 signal->set_id(traffic_light.id());
746 signal->set_current_signal(TrafficLight_Color_Name(traffic_light.color()));
750void SimulationWorldService::UpdatePlanningTrajectory(
753 world_.clear_planning_trajectory();
756 Object *trajectory_point = world_.add_planning_trajectory();
757 trajectory_point->set_timestamp_sec(point.relative_time() + base_time);
758 trajectory_point->set_position_x(point.path_point().
x() +
759 map_service_->GetXOffset());
760 trajectory_point->set_position_y(point.path_point().
y() +
761 map_service_->GetYOffset());
762 trajectory_point->set_speed(point.v());
763 trajectory_point->set_speed_acceleration(point.a());
764 trajectory_point->set_kappa(point.path_point().kappa());
765 trajectory_point->set_dkappa(point.path_point().dkappa());
766 trajectory_point->set_heading(point.path_point().theta());
771 if (trajectory.has_engage_advice()) {
772 world_.set_engage_advice(
778 std::stringstream ss;
779 ss << std::fixed << std::setprecision(2) << data;
783void SimulationWorldService::UpdateRSSInfo(
const ADCTrajectory &trajectory) {
784 if (trajectory.has_rss_info()) {
785 if (trajectory.rss_info().is_rss_safe()) {
786 if (!world_.is_rss_safe()) {
787 this->PublishMonitorMessage(MonitorMessageItem::INFO,
"RSS safe.");
788 world_.set_is_rss_safe(
true);
791 const double next_real_dist = trajectory.rss_info().cur_dist_lon();
792 const double next_rss_safe_dist =
793 trajectory.rss_info().rss_safe_dist_lon();
795 if (std::fabs(current_real_dist_ - next_real_dist) <
796 common::math::kMathEpsilon &&
797 std::fabs(current_rss_safe_dist_ - next_rss_safe_dist) <
798 common::math::kMathEpsilon) {
801 this->PublishMonitorMessage(
802 MonitorMessageItem::ERROR,
803 "RSS unsafe: \ncurrent distance: " +
805 "\nsafe distance: " +
807 world_.set_is_rss_safe(
false);
808 current_real_dist_ = next_real_dist;
809 current_rss_safe_dist_ = next_rss_safe_dist;
814void SimulationWorldService::UpdateMainStopDecision(
815 const apollo::planning::MainDecision &main_decision,
816 double update_timestamp_sec, Object *world_main_decision) {
818 double stop_heading = 0.0;
819 auto decision = world_main_decision->add_decision();
820 decision->set_type(Decision::STOP);
821 if (main_decision.has_not_ready()) {
824 stop_pt.
set_x(world_.auto_driving_car().position_x());
825 stop_pt.
set_y(world_.auto_driving_car().position_y());
826 stop_heading = world_.auto_driving_car().heading();
827 decision->set_stopreason(Decision::STOP_REASON_NOT_READY);
828 }
else if (main_decision.has_estop()) {
831 stop_pt.
set_x(world_.auto_driving_car().position_x());
832 stop_pt.
set_y(world_.auto_driving_car().position_y());
833 stop_heading = world_.auto_driving_car().heading();
834 decision->set_stopreason(Decision::STOP_REASON_EMERGENCY);
835 world_.mutable_auto_driving_car()->set_current_signal(
"EMERGENCY");
838 const apollo::planning::MainStop &stop = main_decision.stop();
839 stop_pt.
set_x(stop.stop_point().x() + map_service_->GetXOffset());
840 stop_pt.
set_y(stop.stop_point().y() + map_service_->GetYOffset());
841 stop_heading = stop.stop_heading();
842 if (stop.has_reason_code()) {
843 SetStopReason(stop.reason_code(), decision);
847 decision->set_position_x(stop_pt.
x());
848 decision->set_position_y(stop_pt.
y());
849 decision->set_heading(stop_heading);
852bool SimulationWorldService::LocateMarker(
853 const apollo::planning::ObjectDecisionType &decision,
854 Decision *world_decision) {
857 if (decision.has_stop() && decision.stop().has_stop_point()) {
858 world_decision->set_type(Decision_Type_STOP);
859 fence_point = decision.stop().stop_point();
860 heading = decision.stop().stop_heading();
861 }
else if (decision.has_follow() && decision.follow().has_fence_point()) {
862 world_decision->set_type(Decision_Type_FOLLOW);
863 fence_point = decision.follow().fence_point();
864 heading = decision.follow().fence_heading();
865 }
else if (decision.has_yield() && decision.yield().has_fence_point()) {
866 world_decision->set_type(Decision_Type_YIELD);
867 fence_point = decision.yield().fence_point();
868 heading = decision.yield().fence_heading();
869 }
else if (decision.has_overtake() && decision.overtake().has_fence_point()) {
870 world_decision->set_type(Decision_Type_OVERTAKE);
871 fence_point = decision.overtake().fence_point();
872 heading = decision.overtake().fence_heading();
877 world_decision->set_position_x(fence_point.
x() + map_service_->GetXOffset());
878 world_decision->set_position_y(fence_point.
y() + map_service_->GetYOffset());
879 world_decision->set_heading(heading);
883void SimulationWorldService::FindNudgeRegion(
884 const apollo::planning::ObjectDecisionType &decision,
885 const Object &world_obj, Decision *world_decision) {
886 std::vector<apollo::common::math::Vec2d> points;
887 for (
auto &polygon_pt : world_obj.polygon_point()) {
888 points.emplace_back(polygon_pt.x(), polygon_pt.y());
893 const std::vector<apollo::common::math::Vec2d> &nudge_points =
895 for (
auto &nudge_pt : nudge_points) {
896 PolygonPoint *poly_pt = world_decision->add_polygon_point();
897 poly_pt->set_x(nudge_pt.x());
898 poly_pt->set_y(nudge_pt.y());
900 world_decision->set_type(Decision_Type_NUDGE);
903void SimulationWorldService::UpdateDecision(
const DecisionResult &decision_res,
904 double header_time) {
906 UpdateTurnSignal(decision_res.vehicle_signal(),
907 world_.mutable_auto_driving_car());
909 const auto &main_decision = decision_res.main_decision();
912 if (main_decision.target_lane_size() > 0) {
913 world_.set_speed_limit(main_decision.target_lane(0).speed_limit());
917 world_.clear_main_decision();
918 Object *world_main_decision = world_.mutable_main_decision();
919 if (main_decision.has_not_ready() || main_decision.has_estop() ||
920 main_decision.has_stop()) {
921 UpdateMainStopDecision(main_decision, header_time, world_main_decision);
923 if (main_decision.has_stop()) {
924 UpdateMainChangeLaneDecision(main_decision.stop(), world_main_decision);
925 }
else if (main_decision.has_cruise()) {
926 UpdateMainChangeLaneDecision(main_decision.cruise(), world_main_decision);
928 if (world_main_decision->decision_size() > 0) {
930 const auto &adc = world_.auto_driving_car();
931 world_main_decision->set_position_x(adc.position_x());
932 world_main_decision->set_position_y(adc.position_y());
933 world_main_decision->set_heading(adc.heading());
934 world_main_decision->set_timestamp_sec(header_time);
938 for (
const auto &obj_decision : decision_res.object_decision().decision()) {
939 if (obj_decision.has_perception_id()) {
940 int id = obj_decision.perception_id();
941 Object &world_obj = obj_map_[std::to_string(
id)];
942 if (!world_obj.has_type()) {
943 world_obj.set_type(Object_Type_VIRTUAL);
944 ADEBUG <<
id <<
" is not a current perception object";
947 for (
const auto &decision : obj_decision.object_decision()) {
948 Decision *world_decision = world_obj.add_decision();
949 world_decision->set_type(Decision_Type_IGNORE);
950 if (decision.has_stop() || decision.has_follow() ||
951 decision.has_yield() || decision.has_overtake()) {
952 if (!LocateMarker(decision, world_decision)) {
953 AWARN <<
"No decision marker position found for object id=" << id;
956 if (decision.has_stop()) {
958 for (
auto obstacle_id : decision.stop().wait_for_obstacle()) {
959 const std::vector<std::string> id_segments =
960 absl::StrSplit(obstacle_id,
'_');
961 if (id_segments.size() > 0) {
962 obj_map_[id_segments[0]].set_yielded_obstacle(
true);
966 }
else if (decision.has_nudge()) {
967 if (world_obj.polygon_point().empty()) {
968 if (world_obj.type() == Object_Type_VIRTUAL) {
969 AWARN <<
"No current perception object with id=" <<
id
970 <<
" for nudge decision";
972 AWARN <<
"No polygon points found for object id=" << id;
976 FindNudgeRegion(decision, world_obj, world_decision);
980 world_obj.set_timestamp_sec(
981 std::max(world_obj.timestamp_sec(), header_time));
986void SimulationWorldService::DownsamplePath(
const common::Path &path,
987 common::Path *downsampled_path) {
990 downsampled_path->set_name(path.name());
991 for (
const size_t index : sampled_indices) {
992 *downsampled_path->add_path_point() =
993 path.path_point(
static_cast<int>(index));
997void SimulationWorldService::UpdatePlanningData(
const PlanningData &data) {
998 auto *planning_data = world_.mutable_planning_data();
1000 size_t max_interval = 10;
1003 if (data.has_scenario()) {
1004 planning_data->mutable_scenario()->CopyFrom(data.scenario());
1007 if (!data.scenario().has_scenario_plugin_type()) {
1008 planning_data->mutable_scenario()->set_scenario_plugin_type(
1009 ScenarioType[planning_data->scenario().scenario_type()]);
1010 planning_data->mutable_scenario()->set_stage_plugin_type(
1011 StageType[planning_data->scenario().stage_type()]);
1016 if (data.has_init_point()) {
1017 auto &planning_path_point = data.init_point().path_point();
1018 auto *world_obj_path_point =
1019 planning_data->mutable_init_point()->mutable_path_point();
1020 world_obj_path_point->set_x(planning_path_point.x() +
1021 map_service_->GetXOffset());
1022 world_obj_path_point->set_y(planning_path_point.y() +
1023 map_service_->GetYOffset());
1024 world_obj_path_point->set_theta(planning_path_point.theta());
1028 planning_data->mutable_chart()->CopyFrom(data.chart());
1031 planning_data->mutable_sl_frame()->CopyFrom(data.sl_frame());
1034 if (data.has_dp_poly_graph()) {
1035 planning_data->mutable_dp_poly_graph()->CopyFrom(data.dp_poly_graph());
1039 planning_data->clear_st_graph();
1040 for (
auto &graph : data.st_graph()) {
1041 auto *st_graph = planning_data->add_st_graph();
1042 st_graph->set_name(graph.name());
1043 st_graph->mutable_boundary()->CopyFrom(graph.boundary());
1044 if (graph.has_kernel_cruise_ref()) {
1045 st_graph->mutable_kernel_cruise_ref()->CopyFrom(
1046 graph.kernel_cruise_ref());
1048 if (graph.has_kernel_follow_ref()) {
1049 st_graph->mutable_kernel_follow_ref()->CopyFrom(
1050 graph.kernel_follow_ref());
1052 if (graph.has_speed_constraint()) {
1053 st_graph->mutable_speed_constraint()->CopyFrom(graph.speed_constraint());
1059 size_t profile_downsample_interval =
1060 std::max(1, (graph.speed_profile_size() / 200));
1061 profile_downsample_interval =
1062 std::min(profile_downsample_interval, max_interval);
1063 DownsampleSpeedPointsByInterval(graph.speed_profile(),
1064 profile_downsample_interval,
1065 st_graph->mutable_speed_profile());
1067 size_t limit_downsample_interval =
1068 std::max(1, (graph.speed_limit_size() / 200));
1069 limit_downsample_interval =
1070 std::min(limit_downsample_interval, max_interval);
1071 DownsampleSpeedPointsByInterval(graph.speed_limit(),
1072 limit_downsample_interval,
1073 st_graph->mutable_speed_limit());
1077 planning_data->clear_speed_plan();
1078 for (
auto &plan : data.speed_plan()) {
1079 if (plan.speed_point_size() > 0) {
1080 auto *downsampled_plan = planning_data->add_speed_plan();
1081 downsampled_plan->set_name(plan.name());
1085 size_t interval = std::max(1, (plan.speed_point_size() / 80));
1086 interval = std::min(interval, max_interval);
1087 DownsampleSpeedPointsByInterval(plan.speed_point(), interval,
1088 downsampled_plan->mutable_speed_point());
1093 planning_data->clear_path();
1094 for (
auto &path : data.path()) {
1095 DownsamplePath(path, planning_data->add_path());
1099 planning_data->clear_pull_over();
1100 if (data.has_pull_over()) {
1101 planning_data->mutable_pull_over()->CopyFrom(data.pull_over());
1105 world_.clear_traffic_signal();
1106 if (data.has_signal_light() && data.signal_light().signal_size() > 0) {
1107 TrafficLight::Color current_signal = TrafficLight::UNKNOWN;
1108 int green_light_count = 0;
1110 for (
auto &signal : data.signal_light().signal()) {
1111 switch (signal.color()) {
1112 case TrafficLight::RED:
1113 case TrafficLight::YELLOW:
1114 case TrafficLight::BLACK:
1115 current_signal = signal.color();
1117 case TrafficLight::GREEN:
1118 green_light_count++;
1125 if (green_light_count == data.signal_light().signal_size()) {
1126 current_signal = TrafficLight::GREEN;
1129 world_.mutable_traffic_signal()->set_current_signal(
1130 TrafficLight_Color_Name(current_signal));
1135void SimulationWorldService::UpdateSimulationWorld(
1139 UpdatePlanningTrajectory(trajectory);
1141 UpdateRSSInfo(trajectory);
1143 UpdateDecision(trajectory.
decision(), header_time);
1148 latency.set_timestamp_sec(header_time);
1150 (*world_.mutable_latency())[
"planning"] = latency;
1153void SimulationWorldService::CreatePredictionTrajectory(
1155 for (
const auto &traj : obstacle.trajectory()) {
1156 Prediction *prediction = world_object->add_prediction();
1157 prediction->set_probability(traj.probability());
1159 std::vector<PathPoint> points;
1160 for (
const auto &point : traj.trajectory_point()) {
1161 points.push_back(point.path_point());
1163 auto sampled_indices = DownsampleByAngle(points, kAngleThreshold);
1165 for (
auto index : sampled_indices) {
1166 const auto &point = points[index];
1167 PolygonPoint *world_point = prediction->add_predicted_trajectory();
1168 world_point->set_x(point.
x() + map_service_->GetXOffset());
1169 world_point->set_y(point.
y() + map_service_->GetYOffset());
1171 const TrajectoryPoint &traj_point = traj.trajectory_point(index);
1172 if (traj_point.has_gaussian_info()) {
1174 traj_point.gaussian_info();
1176 auto *ellipse = world_point->mutable_gaussian_info();
1177 ellipse->set_ellipse_a(gaussian.ellipse_a());
1178 ellipse->set_ellipse_b(gaussian.ellipse_b());
1179 ellipse->set_theta_a(gaussian.theta_a());
1186void SimulationWorldService::UpdateSimulationWorld(
1196 CreatePredictionTrajectory(obstacle, &world_obj);
1199 if (obstacle.has_priority()) {
1200 world_obj.mutable_obstacle_priority()->CopyFrom(obstacle.
priority());
1204 if (obstacle.has_interactive_tag()) {
1205 world_obj.mutable_interactive_tag()->CopyFrom(obstacle.
interactive_tag());
1208 world_obj.set_timestamp_sec(
1209 std::max(obstacle.
timestamp(), world_obj.timestamp_sec()));
1214void SimulationWorldService::UpdateSimulationWorld(
1218 boost::shared_lock<boost::shared_mutex> reader_lock(route_paths_mutex_);
1219 if (world_.has_routing_time() &&
1226 std::vector<Path> paths;
1227 if (!map_service_->GetPathsFromRouting(routing_response, &paths)) {
1231 world_.clear_route_path();
1233 std::vector<RoutePath> route_paths;
1234 for (
const Path &path : paths) {
1236 auto sampled_indices =
1237 DownsampleByAngle(path.path_points(), kAngleThreshold);
1239 route_paths.emplace_back();
1240 RoutePath *route_path = &route_paths.back();
1241 for (
const size_t index : sampled_indices) {
1242 const auto &path_point = path.path_points()[index];
1244 route_point->set_x(path_point.x() + map_service_->GetXOffset());
1245 route_point->set_y(path_point.y() + map_service_->GetYOffset());
1249 if (FLAGS_sim_world_with_routing_path) {
1250 auto *new_path = world_.add_route_path();
1251 *new_path = *route_path;
1255 boost::unique_lock<boost::shared_mutex> writer_lock(route_paths_mutex_);
1256 std::swap(route_paths, route_paths_);
1261Json SimulationWorldService::GetRoutePathAsJson()
const {
1263 response[
"routePath"] = Json::array();
1264 std::vector<RoutePath> route_paths;
1266 boost::shared_lock<boost::shared_mutex> reader_lock(route_paths_mutex_);
1267 response[
"routingTime"] = world_.routing_time();
1268 route_paths = route_paths_;
1270 for (
const auto &route_path : route_paths) {
1272 path[
"point"] = Json::array();
1273 for (
const auto &route_point : route_path.point()) {
1274 path[
"point"].push_back({{
"x", route_point.x()},
1275 {
"y", route_point.y()},
1276 {
"z", route_point.z()}});
1278 response[
"routePath"].push_back(path);
1283void SimulationWorldService::ReadPlanningCommandFromFile(
1284 const std::string &planning_command_file) {
1285 auto planning_command = std::make_shared<PlanningCommand>();
1287 AWARN <<
"Unable to read planning command from file: "
1288 << planning_command_file;
1291 AINFO <<
"Loaded planning command from " << planning_command_file;
1296 auto planning_command_writer =
1297 node_->CreateWriter<PlanningCommand>(FLAGS_planning_command);
1298 planning_command_writer->Write(planning_command);
1299 AINFO <<
"Published PlanningCommand read from file.";
1303void SimulationWorldService::UpdateSimulationWorld(
1305 auto *control_data = world_.mutable_control_data();
1307 control_data->set_timestamp_sec(header_time);
1310 latency.set_timestamp_sec(header_time);
1312 (*world_.mutable_latency())[
"control"] = latency;
1314 if (control_command.has_debug()) {
1315 auto &debug = control_command.
debug();
1316 if (debug.has_simple_lon_debug() && debug.has_simple_lat_debug()) {
1318 if (simple_lon.has_station_error()) {
1319 control_data->set_station_error(simple_lon.station_error());
1321 auto &simple_lat = debug.simple_lat_debug();
1322 if (simple_lat.has_heading_error()) {
1323 control_data->set_heading_error(simple_lat.heading_error());
1325 if (simple_lat.has_lateral_error()) {
1326 control_data->set_lateral_error(simple_lat.lateral_error());
1328 if (simple_lat.has_current_target_point()) {
1329 control_data->mutable_current_target_point()->CopyFrom(
1330 simple_lat.current_target_point());
1332 }
else if (debug.has_simple_mpc_debug()) {
1333 auto &simple_mpc = debug.simple_mpc_debug();
1334 if (simple_mpc.has_station_error()) {
1335 control_data->set_station_error(simple_mpc.station_error());
1337 if (simple_mpc.has_heading_error()) {
1338 control_data->set_heading_error(simple_mpc.heading_error());
1340 if (simple_mpc.has_lateral_error()) {
1341 control_data->set_lateral_error(simple_mpc.lateral_error());
1348void SimulationWorldService::UpdateSimulationWorld(
1350 world_.clear_navigation_path();
1352 if (navigation_path.has_path()) {
1353 DownsamplePath(navigation_path.path(), world_.add_navigation_path());
1359void SimulationWorldService::UpdateSimulationWorld(
const MapMsg &map_msg) {
1360 if (map_msg.has_hdmap()) {
1361 relative_map_.CopyFrom(map_msg.
hdmap());
1362 for (
int i = 0; i < relative_map_.lane_size(); ++i) {
1363 auto *lane = relative_map_.mutable_lane(i);
1364 lane->clear_left_sample();
1365 lane->clear_right_sample();
1366 lane->clear_left_road_sample();
1367 lane->clear_right_road_sample();
1369 DownsampleCurve(lane->mutable_central_curve());
1370 DownsampleCurve(lane->mutable_left_boundary()->mutable_curve());
1371 DownsampleCurve(lane->mutable_right_boundary()->mutable_curve());
1377void SimulationWorldService::UpdateSimulationWorld(
1379 const int updated_size = std::min(monitor_msg.item_size(),
1380 SimulationWorldService::kMaxMonitorItems);
1382 for (
int idx = 0; idx < updated_size; ++idx) {
1383 auto *notification = world_.add_notification();
1384 notification->mutable_item()->CopyFrom(monitor_msg.
item(idx));
1389 world_.notification_size() - SimulationWorldService::kMaxMonitorItems;
1390 if (remove_size > 0) {
1391 auto *notifications = world_.mutable_notification();
1392 notifications->erase(notifications->begin(),
1393 notifications->begin() + remove_size);
1397void SimulationWorldService::UpdateMonitorMessages() {
1398 std::list<std::shared_ptr<MonitorMessage>> monitor_msgs;
1400 std::unique_lock<std::mutex> lock(monitor_msgs_mutex_);
1401 monitor_msgs = monitor_msgs_;
1402 monitor_msgs_.clear();
1405 for (
const auto &monitor_msg : monitor_msgs) {
1406 UpdateSimulationWorld(*monitor_msg);
1410void SimulationWorldService::DumpMessages() {
1411 DumpMessageFromReader(chassis_reader_.get());
1412 DumpMessageFromReader(prediction_obstacle_reader_.get());
1413 DumpMessageFromReader(planning_command_reader_.get());
1414 DumpMessageFromReader(localization_reader_.get());
1415 DumpMessageFromReader(planning_reader_.get());
1416 DumpMessageFromReader(control_command_reader_.get());
1417 DumpMessageFromReader(perception_obstacle_reader_.get());
1418 DumpMessageFromReader(perception_traffic_light_reader_.get());
1419 DumpMessageFromReader(relative_map_reader_.get());
1420 DumpMessageFromReader(navigation_reader_.get());
1421 DumpMessageFromReader(task_reader_.get());
1424void SimulationWorldService::PublishNavigationInfo(
1425 const std::shared_ptr<NavigationInfo> &navigation_info) {
1426 FillHeader(FLAGS_dreamview_module_name, navigation_info.get());
1427 navigation_writer_->Write(navigation_info);
1430void SimulationWorldService::PublishLaneFollowCommand(
1431 const std::shared_ptr<LaneFollowCommand> &lane_follow_command) {
1432 FillHeader(FLAGS_dreamview_module_name, lane_follow_command.get());
1433 lane_follow_command_client_->SendRequest(lane_follow_command);
1436void SimulationWorldService::PublishValetParkingCommand(
1437 const std::shared_ptr<ValetParkingCommand> &valet_parking_command) {
1438 FillHeader(FLAGS_dreamview_module_name, valet_parking_command.get());
1439 valet_parking_command_client_->SendRequest(valet_parking_command);
1442void SimulationWorldService::PublishActionCommand(
1443 const std::shared_ptr<ActionCommand> &action_command) {
1444 FillHeader(FLAGS_dreamview_module_name, action_command.get());
1445 action_command_client_->SendRequest(action_command);
1448void SimulationWorldService::PublishTask(
const std::shared_ptr<Task> &task) {
1449 FillHeader(FLAGS_dreamview_module_name, task.get());
1450 task_writer_->Write(task);
1453void SimulationWorldService::PublishMonitorMessage(
1455 const std::string &msg) {
1456 monitor_logger_buffer_.AddMonitorMsgItem(log_level, msg);
1457 monitor_logger_buffer_.Publish();
1460void SimulationWorldService::UpdateVehicleParam() {
1461 auto &vehicle_param = VehicleConfigHelper::GetConfig().vehicle_param();
1462 world_.mutable_vehicle_param()->CopyFrom(vehicle_param);
@Brief This is a helper class that can load vehicle configurations.
The class of polygon in 2-D.
Polygon2d ExpandByDistance(const double distance) const
Expand this polygon by a distance.
const std::vector< Vec2d > & points() const
Get the vertices of the polygon.
Implements a class of 2-dimensional vectors.
void set_x(const double x)
Setter for x component
double y() const
Getter for y component
double x() const
Getter for x component
void set_y(const double y)
Setter for y component
a singleton clock that can be used to get the current timestamp.
static Time Now()
PRECISION >= 1000000 means the precision is at least 1us.
double ToSecond() const
convert time to second.
SimulationWorldService(const MapService *map_service, bool routing_from_file=false)
Constructor of SimulationWorldService.
static constexpr int kMaxMonitorItems
double QuaternionToHeading(const double qw, const double qx, const double qy, const double qz)
std::vector< size_t > DownsampleByAngle(const Points &points, const double angle_threshold)
Downsample the points on the path according to the angle.
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
std::unique_ptr< Node > CreateNode(const std::string &node_name, const std::string &name_space)
std::string formatDoubleToString(const double data)
Contains a number of helper functions related to quaternions.
optional GearPosition gear_location
optional apollo::common::VehicleSignal signal
optional float steering_percentage
optional float brake_percentage
optional int32 battery_soc_percentage
optional float throttle_percentage
optional bool emergency_light
optional TurnSignal turn_signal
repeated MonitorMessageItem item
optional apollo::common::Header header
optional apollo::common::Header header
optional LatencyStats latency_stats
optional SimpleLongitudinalDebug simple_lon_debug
optional double total_time_ms
@ STOP_REASON_DESTINATION
@ STOP_REASON_HEAD_VEHICLE
@ DISENGAGE_AUTO_STEER_ONLY
@ DISENGAGE_CHASSIS_ERROR
@ DISENGAGE_AUTO_SPEED_ONLY
optional apollo::common::Header header
optional apollo::localization::Pose localization
optional apollo::localization::Pose pose
optional apollo::common::Header header
optional V2XInformation v2x_info
optional SubType sub_type
optional LaneMarkers lane_marker
repeated PerceptionObstacle perception_obstacle
optional CIPVInfo cipv_info
repeated TrafficLight traffic_light
optional apollo::common::EngageAdvice engage_advice
optional LatencyStats latency_stats
optional apollo::common::Header header
optional apollo::planning::DecisionResult decision
optional apollo::planning_internal::Debug debug
optional double total_time_ms
optional apollo::common::Header header
optional apollo::routing::RoutingResponse lane_follow_command
optional PlanningData planning_data
optional ObstacleInteractiveTag interactive_tag
optional apollo::perception::PerceptionObstacle perception_obstacle
optional ObstaclePriority priority
optional double timestamp
repeated PredictionObstacle prediction_obstacle
optional apollo::hdmap::Map hdmap
repeated NavigationPath navigation_path