Pārlūkot izejas kodu

change for apollo. use gui start apollo ok. some work need complete after 1 month.

yuchuli 3 mēneši atpakaļ
vecāks
revīzija
56789acb3d

+ 3 - 0
src/apollo/change2/Readme.md

@@ -0,0 +1,3 @@
+change2配合pilot_apollo_bridge_gui使用。
+主要修改是,dreamview_plus去掉了qt相关代码,不依赖qt。
+然后pilot_apollo_bridge_gui负责apollo系统的启动和关闭。pilot_apollo_bridge_gui具备cyber通信和modulecomm通信功能,但不直接读写apollo系统的消息。

+ 53 - 0
src/apollo/change2/dreamview_plus/BUILD

@@ -0,0 +1,53 @@
+load("//tools/platform:build_defs.bzl", "copts_if_teleop")
+load("//tools:apollo_package.bzl", "apollo_package", "apollo_cc_binary","apollo_qt_library")
+load("//tools:cpplint.bzl", "cpplint")
+
+package(default_visibility = ["//visibility:public"])
+
+DREAMVIEW_COPTS = ['-DMODULE_NAME=\\"dreamview_plus\\"  ']
+
+filegroup(
+    name = "frontend",
+    srcs = glob(["frontend/dist/**/*"]),
+)
+
+apollo_cc_binary(
+    name = "dreamview_plus",
+    srcs = ["main.cc"],
+    copts = DREAMVIEW_COPTS + copts_if_teleop(),
+    data = [
+        ":frontend",
+    ],
+    linkopts = [
+        "-ltcmalloc",
+        "-lprofiler",
+        "-lGeographicLib",
+    ],
+    deps = [
+        "//cyber",
+        "//modules/dreamview_plus/backend:apollo_dreamview_plus_backend",
+        "//modules/dreamview_plus/proto:gpsimu_proto",
+        "//modules/dreamview_plus/proto:apolloctrlcmd_proto",
+        "//modules/dreamview_plus/proto:objectarray_proto",
+        "//modules/common_msgs/localization_msgs:gps_proto",
+        "//modules/common_msgs/localization_msgs:localization_proto",
+        "//modules/common_msgs/sensor_msgs:ins_cc_proto",
+        "//modules/common_msgs/localization_msgs:imu_cc_proto",
+        "//modules/common_msgs/control_msgs:control_cmd_proto",
+        "//modules/common_msgs/perception_msgs:perception_obstacle_proto",
+    ],
+)
+
+filegroup(
+    name = "dreamview_conf",
+    srcs = glob([
+        "conf/*.conf",
+        "conf/*.txt",
+        "conf/hmi_modes/*.txt",
+        "launch/*.launch",
+    ]),
+)
+
+apollo_package()
+
+cpplint()

+ 324 - 0
src/apollo/change2/dreamview_plus/main.cc

@@ -0,0 +1,324 @@
+/******************************************************************************
+ * 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.
+ *****************************************************************************/
+
+#include <filesystem>
+
+#include "gperftools/heap-profiler.h"
+#include "gperftools/malloc_extension.h"
+#include "gperftools/profiler.h"
+
+#include "cyber/common/global_data.h"
+#include "cyber/init.h"
+
+#include <iostream>
+#include "modules/dreamview_plus/backend/dreamview.h"
+
+
+#include "modules/dreamview_plus/proto/gpsimu.pb.h"
+#include "modules/dreamview_plus/proto/apolloctrlcmd.pb.h"
+#include "modules/dreamview_plus/proto/objectarray.pb.h"
+
+#include "modules/common_msgs/localization_msgs/localization.pb.h"
+#include "modules/common_msgs/control_msgs/control_cmd.pb.h"
+#include "modules/common_msgs/perception_msgs/perception_obstacle.pb.h"
+
+#include <functional>
+
+#include <GeographicLib/MGRS.hpp>
+#include <GeographicLib/UTMUPS.hpp>
+
+#include "modules/common/math/math_utils.h"
+#include "modules/common/math/quaternion.h"
+#include "modules/common/util/message_util.h"
+#include "modules/common/util/util.h"
+
+
+
+std::shared_ptr<apollo::cyber::Writer<apollo::perception::PerceptionObstacles>>  perception_writer_ = nullptr; 
+   
+std::shared_ptr<apollo::cyber::Writer<apollo::localization::LocalizationEstimate>>
+      localization_writer_;
+      
+std::shared_ptr<apollo::cyber::Writer<iv::apollo::apolloctrlcmd>>
+      control_command_writer_;
+
+std::shared_ptr<apollo::cyber::Reader<apollo::control::ControlCommand>>
+      control_command_reader_;
+      
+std::shared_ptr<apollo::cyber::Reader<iv::gps::gpsimu>>
+      gps_reader_;
+
+std::shared_ptr<apollo::cyber::Reader<iv::lidar::objectarray>>
+      obj_reader_;
+      
+void * gpadecision;
+
+double gfutm_x = 0;
+double gfutm_y = 0;
+double gfutm_hdg = 0;
+
+using apollo::common::Point3D;
+using apollo::common::math::HeadingToQuaternion;
+using apollo::common::Quaternion;
+
+using apollo::common::math::InverseQuaternionRotate;
+using apollo::common::util::FillHeader;
+
+void TransformToVRF(const Point3D &point_mrf, const Quaternion &orientation,
+                    Point3D *point_vrf) {
+  Eigen::Vector3d v_mrf(point_mrf.x(), point_mrf.y(), point_mrf.z());
+  auto v_vrf = InverseQuaternionRotate(orientation, v_mrf);
+  point_vrf->set_x(v_vrf.x());
+  point_vrf->set_y(v_vrf.y());
+  point_vrf->set_z(v_vrf.z());
+}
+
+void PublishLocalization(const double x,const double y,const double z,const double yaw,const double v,const double kappa,const double a) {
+  auto localization = std::make_shared<apollo::localization::LocalizationEstimate>();
+  FillHeader("SimPerfectControl", localization.get());
+  auto *pose = localization->mutable_pose();
+
+  pose->mutable_position()->set_x(x);
+  pose->mutable_position()->set_y(y);
+  pose->mutable_position()->set_z(z);
+  // Set orientation and heading
+  double cur_theta = yaw;
+
+
+
+  Eigen::Quaternion<double> cur_orientation =
+      HeadingToQuaternion<double>(cur_theta);
+  pose->mutable_orientation()->set_qw(cur_orientation.w());
+  pose->mutable_orientation()->set_qx(cur_orientation.x());
+  pose->mutable_orientation()->set_qy(cur_orientation.y());
+  pose->mutable_orientation()->set_qz(cur_orientation.z());
+  pose->set_heading(cur_theta);
+
+  // Set linear_velocity
+  pose->mutable_linear_velocity()->set_x(std::cos(cur_theta) * v);
+  pose->mutable_linear_velocity()->set_y(std::sin(cur_theta) * v);
+  pose->mutable_linear_velocity()->set_z(0);
+
+  // Set angular_velocity in both map reference frame and vehicle reference
+  // frame
+  pose->mutable_angular_velocity()->set_x(0);
+  pose->mutable_angular_velocity()->set_y(0);
+  pose->mutable_angular_velocity()->set_z(v*kappa);
+
+  TransformToVRF(pose->angular_velocity(), pose->orientation(),
+                 pose->mutable_angular_velocity_vrf());
+
+  // Set linear_acceleration in both map reference frame and vehicle reference
+  // frame
+  auto *linear_acceleration = pose->mutable_linear_acceleration();
+  linear_acceleration->set_x(std::cos(cur_theta) * a);
+  linear_acceleration->set_y(std::sin(cur_theta) * a);
+  linear_acceleration->set_z(0);
+
+  TransformToVRF(pose->linear_acceleration(), pose->orientation(),
+                 pose->mutable_linear_acceleration_vrf());
+  localization_writer_->Write(localization);
+
+}
+
+
+void onControl(
+    const std::shared_ptr<apollo::control::ControlCommand> &xCmd) {
+//  std::lock_guard<std::mutex> lock(mutex_);
+
+//  std::cout<<"steer: "<<xCmd->steering_target()<<" acc: "<<xCmd->acceleration()<<" brake:"<<xCmd->brake()<<std::endl;
+  
+    auto xctrlcmd_ptr = std::make_shared<iv::apollo::apolloctrlcmd>();
+    xctrlcmd_ptr->set_acceleration(xCmd->acceleration());
+    xctrlcmd_ptr->set_brake(xCmd->brake()); 
+    xctrlcmd_ptr->set_steering_target(xCmd->steering_target());
+    
+    control_command_writer_->Write(xctrlcmd_ptr);
+}
+
+void onGPS(const std::shared_ptr<iv::gps::gpsimu> &xGPS)
+{
+    double flon = xGPS->lon();
+    double flat = xGPS->lat();
+    
+    double utm_x,utm_y; 
+    int zone{};
+    bool is_north{};
+    GeographicLib::UTMUPS::Forward(flat, flon, zone, is_north, utm_x,utm_y);
+    
+    PublishLocalization(utm_x,utm_y,xGPS->height(),(90-xGPS->heading())*M_PI/180.0,xGPS->speed(),0,0);
+    
+}
+
+void onLidarTrack(const std::shared_ptr<iv::lidar::objectarray> &xLidar_ptr)
+{
+  int nsize = static_cast<int>(xLidar_ptr->obj_size());
+  int i;
+  auto perceptionobjs = std::make_shared<apollo::perception::PerceptionObstacles>();
+  FillHeader("SimPerfectControl", perceptionobjs.get());
+  for(i=0;i<nsize;i++){
+
+    iv::lidar::lidarobject * plidarobj = xLidar_ptr->mutable_obj(i);
+    auto pobj = perceptionobjs->add_perception_obstacle();
+
+    double xbase = gfutm_x;
+    double ybase = gfutm_y;
+    pobj->set_id(i);
+    apollo::common::Point3D  * ppos = new apollo::common::Point3D();
+    double xrot = 0;
+    double yrot = 0;
+  //  std::cout<<" obj x: "<<plidarobj->position().x()<<" y:"<<plidarobj->position().y()<<std::endl;
+    xrot = plidarobj->position().y() * cos(gfutm_hdg) - plidarobj->position().x() * (-1.0) * sin(gfutm_hdg);
+    yrot = plidarobj->position().y() * sin(gfutm_hdg) + plidarobj->position().x() * (-1.0) * cos(gfutm_hdg);
+    ppos->set_x(xrot + xbase);
+    ppos->set_y(yrot + ybase);
+    ppos->set_z(plidarobj->position().z());
+    pobj->set_allocated_position(ppos);
+
+    double fobjhdg = plidarobj->tyaw() + gfutm_hdg;
+
+    double xp[4],yp[4];
+    double fpedlen = plidarobj->dimensions().x();
+    double fpedwidth = plidarobj->dimensions().y();
+    double fhdg = fobjhdg - M_PI/2.0;
+    double x = xrot;
+    double y = yrot;
+    xp[0] = x + (0 - fpedlen/2.0) * cos(fhdg) - (0 - fpedwidth/2.0) * sin(fhdg);
+    yp[0] = y + (0 - fpedlen/2.0) * sin(fhdg) + (0 - fpedwidth/2.0) * cos(fhdg);
+    xp[1] = x + (0 + fpedlen/2.0) * cos(fhdg) - (0 - fpedwidth/2.0) * sin(fhdg);
+    yp[1] = y + (0 + fpedlen/2.0) * sin(fhdg) + (0 - fpedwidth/2.0) * cos(fhdg);
+    xp[2] = x + (0 + fpedlen/2.0) * cos(fhdg) - (0 + fpedwidth/2.0) * sin(fhdg);
+    yp[2] = y + (0 + fpedlen/2.0) * sin(fhdg) + (0 + fpedwidth/2.0) * cos(fhdg);
+    xp[3] = x + (0 - fpedlen/2.0) * cos(fhdg) - (0 + fpedwidth/2.0) * sin(fhdg);
+    yp[3] = y + (0 - fpedlen/2.0) * sin(fhdg) + (0 + fpedwidth/2.0) * cos(fhdg);
+    apollo::common::Point3D * p1 = pobj->add_polygon_point();
+    p1->set_x(xp[1]+ xbase);p1->set_y(yp[1]+ ybase);p1->set_z(0);
+    apollo::common::Point3D * p2 = pobj->add_polygon_point();
+    p2->set_x(xp[2]+ xbase);p2->set_y(yp[2]+ ybase);p2->set_z(0);
+    apollo::common::Point3D * p3 = pobj->add_polygon_point();
+    p3->set_x(xp[3]+ xbase);p3->set_y(yp[3]+ ybase);p3->set_z(0);
+    apollo::common::Point3D * p4 = pobj->add_polygon_point();
+    p4->set_x(xp[0]+ xbase);p4->set_y(yp[0]+ ybase);p4->set_z(0);
+
+    pobj->set_length(fpedlen);
+    pobj->set_width(fpedwidth);
+    pobj->set_height(plidarobj->dimensions().z());
+
+    pobj->set_tracking_time(1.0);
+
+    apollo::common::Point3D  * pvel = new apollo::common::Point3D();
+    pvel->set_x(0); pvel->set_y(0); pvel->set_z(0);
+    pobj->set_allocated_velocity(pvel);
+
+    apollo::common::Point3D * paccel = new apollo::common::Point3D();
+    paccel->set_x(0); paccel->set_y(0); paccel->set_z(0);
+    pobj->set_allocated_acceleration(paccel);
+
+    pobj->set_type(apollo::perception::PerceptionObstacle_Type_VEHICLE);
+
+    
+  }
+
+  perception_writer_->Write(perceptionobjs);
+    
+}
+
+
+
+
+int main(int argc, char* argv[]) {
+
+  std::cout<<" hello ,  adc dreamviewplus. 0211 10:06"<<std::endl;
+      double utm_x,utm_y; 
+    int zone{};
+    bool is_north{};
+    GeographicLib::UTMUPS::Forward(39, 117, zone, is_north, utm_x,utm_y);
+    std::cout<<"utm x: "<<utm_x<<" utm y: "<<utm_y<<std::endl;
+
+  // set working directory to APOLLO_RUNTIME_PATH for relative file paths
+  const char* apollo_runtime_path = std::getenv("APOLLO_RUNTIME_PATH");
+  if (apollo_runtime_path != nullptr) {
+    if (std::filesystem::is_directory(
+            std::filesystem::status(apollo_runtime_path))) {
+      std::filesystem::current_path(apollo_runtime_path);
+    }
+  }
+  google::ParseCommandLineFlags(&argc, &argv, true);
+  // Added by caros to improve dv performance
+
+  std::signal(SIGTERM, [](int sig) {
+    apollo::cyber::OnShutdown(sig);
+    if (FLAGS_dv_cpu_profile) {
+      ProfilerStop();
+    }
+    if (FLAGS_dv_heap_profile) {
+      HeapProfilerDump("Befor shutdown");
+      HeapProfilerStop();
+    }
+  });
+
+  std::signal(SIGINT, [](int sig) {
+    apollo::cyber::OnShutdown(sig);
+    if (FLAGS_dv_cpu_profile) {
+      ProfilerStop();
+    }
+    if (FLAGS_dv_heap_profile) {
+      HeapProfilerDump("Befor shutdown");
+      HeapProfilerStop();
+    }
+  });
+
+  if (FLAGS_dv_cpu_profile) {
+    auto base_name_cpu = std::string(argv[0]) + "_cpu" + std::string(".prof");
+    ProfilerStart(base_name_cpu.c_str());
+  }
+  if (FLAGS_dv_heap_profile) {
+    auto base_name_heap = std::string(argv[0]) + "_heap" + std::string(".prof");
+    HeapProfilerStart(base_name_heap.c_str());
+  }
+
+  apollo::cyber::GlobalData::Instance()->SetProcessGroup("dreamview_sched");
+  apollo::cyber::Init(argv[0]);
+  
+  auto talker_node = apollo::cyber::CreateNode("pilot_apollo_bridge");
+  
+  localization_writer_ = talker_node->CreateWriter<apollo::localization::LocalizationEstimate>("/apollo/localization/adcpose");
+
+  perception_writer_ = talker_node->CreateWriter<apollo::perception::PerceptionObstacles>("/apollo/perception/obstacles");
+  
+  control_command_writer_ = talker_node->CreateWriter<iv::apollo::apolloctrlcmd>(
+      "/adc/control");
+	
+  control_command_reader_ = talker_node->CreateReader<apollo::control::ControlCommand>(
+      "/apollo/control",onControl);
+      
+  gps_reader_ = talker_node->CreateReader<iv::gps::gpsimu>(
+      "/adc/gps",onGPS);
+      
+  obj_reader_ = talker_node->CreateReader<iv::lidar::objectarray>(
+      "/adc/obj",onLidarTrack);
+      
+  
+
+  apollo::dreamview::Dreamview dreamview;
+  const bool init_success = dreamview.Init().ok() && dreamview.Start().ok();
+  if (!init_success) {
+    AERROR << "Failed to initialize dreamview server";
+    return -1;
+  }
+  apollo::cyber::WaitForShutdown();
+  return 0;
+}

+ 658 - 0
src/apollo/change2/sim_perfect_control.cc

@@ -0,0 +1,658 @@
+/******************************************************************************
+ * 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.
+ *****************************************************************************/
+
+#include "modules/dreamview/backend/common/sim_control_manager/dynamic_model/perfect_control/sim_perfect_control.h"
+
+#include "cyber/common/file.h"
+#include "cyber/time/clock.h"
+#include "modules/common/adapters/adapter_gflags.h"
+#include "modules/common/math/linear_interpolation.h"
+#include "modules/common/math/math_utils.h"
+#include "modules/common/math/quaternion.h"
+#include "modules/common/util/message_util.h"
+#include "modules/common/util/util.h"
+
+#include <math.h>
+
+namespace apollo {
+namespace dreamview {
+
+using apollo::canbus::Chassis;
+using apollo::common::Header;
+using apollo::common::Point3D;
+using apollo::common::Quaternion;
+using apollo::common::TrajectoryPoint;
+using apollo::common::math::HeadingToQuaternion;
+using apollo::common::math::InterpolateUsingLinearApproximation;
+using apollo::common::math::InverseQuaternionRotate;
+using apollo::common::util::FillHeader;
+using apollo::cyber::Clock;
+using apollo::localization::LocalizationEstimate;
+using apollo::planning::ADCTrajectory;
+using apollo::planning::PlanningCommand;
+using apollo::prediction::PredictionObstacles;
+using apollo::relative_map::NavigationInfo;
+using Json = nlohmann::json;
+
+#include <iostream>
+#include <fstream>
+#include <chrono>
+#include <iomanip>
+void  adclog1(const char * strlog){
+    std::ofstream myFile;
+ //   myFile.open("/home/yuchuli/adclog.txt", std::ios_base::app);
+    myFile.open("/apollo/adclog.txt", std::ios_base::app);
+    if(myFile.is_open())
+    {       
+        auto now = std::chrono::system_clock::now();
+//        std::time_t now_c = std::chrono::system_clock::to_time_t(now - std::chrono::hours(24));
+        std::time_t now_c = std::chrono::system_clock::to_time_t(now);
+        myFile<<std::put_time(std::localtime(&now_c), "%Y-%m-%d %X  ") <<strlog<<std::endl;
+        myFile.close();
+    }
+    else
+    {
+        std::cout<<"open fail"<<std::endl;
+    }
+}
+
+// gflags定义类型	描述
+DEFINE_bool(use_realveh, true, "set use real vehicle");   // bool位整型
+ 
+DECLARE_bool(use_realveh);
+
+double fNowVel = 0.0;
+
+void LoadConfigFile(const std::string& file_path) {
+    std::ifstream config_file(file_path);
+    if (!config_file.is_open()) {
+        std::cout << "Failed to open configuration file: " << file_path << std::endl;
+        return;
+    }
+    std::string line;
+    while (std::getline(config_file, line)) {
+        std::istringstream iss(line);
+        std::string key, value;
+        if (std::getline(iss, key, '=') && std::getline(iss, value)) {
+            // 去除前后的空白字符
+            std::size_t first = value.find_first_not_of(" \t");
+            std::size_t last = value.find_last_not_of(" \t");
+            if (first != std::string::npos && last != std::string::npos) {
+                value = value.substr(first, last - first + 1);
+                // 这里可以处理不同的 flag 类型,这里简单处理为 string 类型
+                if (key == "-use_realveh") {
+                    google::SetCommandLineOption("use_realveh", value.c_str());
+                }
+                // 可以添加更多类型的处理
+            }
+        }
+    }
+    config_file.close();
+}
+
+namespace {
+
+void TransformToVRF(const Point3D &point_mrf, const Quaternion &orientation,
+                    Point3D *point_vrf) {
+  Eigen::Vector3d v_mrf(point_mrf.x(), point_mrf.y(), point_mrf.z());
+  auto v_vrf = InverseQuaternionRotate(orientation, v_mrf);
+  point_vrf->set_x(v_vrf.x());
+  point_vrf->set_y(v_vrf.y());
+  point_vrf->set_z(v_vrf.z());
+}
+
+bool IsSameHeader(const Header &lhs, const Header &rhs) {
+  return lhs.sequence_num() == rhs.sequence_num() &&
+         lhs.timestamp_sec() == rhs.timestamp_sec();
+}
+
+}  // namespace
+
+SimPerfectControl::SimPerfectControl(const MapService *map_service)
+    : SimControlBase(),
+      map_service_(map_service),
+      node_(cyber::CreateNode("sim_perfect_control")),
+      current_trajectory_(std::make_shared<ADCTrajectory>()) {
+  InitTimerAndIO();
+  
+  LoadConfigFile("/apollo/adcconfig.txt");
+  if(FLAGS_use_realveh == true){
+	  adclog1("use real vehicle.");
+  }else{
+	  adclog1("use simulate.");
+  }
+}
+
+void SimPerfectControl::InitTimerAndIO() {
+  std::cout<<"init timer."<<std::endl;
+  localization_reader_ =
+      node_->CreateReader<LocalizationEstimate>(FLAGS_localization_topic);
+  localization_adc_reader_ = node_->CreateReader<LocalizationEstimate>(
+      "/apollo/localization/adcpose",
+      [this](const std::shared_ptr<LocalizationEstimate> &xloc) {
+        this->onADCLoc(xloc);
+      });
+  planning_reader_ = node_->CreateReader<ADCTrajectory>(
+      FLAGS_planning_trajectory_topic,
+      [this](const std::shared_ptr<ADCTrajectory> &trajectory) {
+        this->OnPlanning(trajectory);
+      });
+  planning_command_reader_ = node_->CreateReader<PlanningCommand>(
+      FLAGS_planning_command,
+      [this](const std::shared_ptr<PlanningCommand> &planning_command) {
+        this->OnPlanningCommand(planning_command);
+      });
+  navigation_reader_ = node_->CreateReader<NavigationInfo>(
+      FLAGS_navigation_topic,
+      [this](const std::shared_ptr<NavigationInfo> &navigation_info) {
+        this->OnReceiveNavigationInfo(navigation_info);
+      });
+  prediction_reader_ = node_->CreateReader<PredictionObstacles>(
+      FLAGS_prediction_topic,
+      [this](const std::shared_ptr<PredictionObstacles> &obstacles) {
+        this->OnPredictionObstacles(obstacles);
+      });
+  
+ control_command_reader_ = node_->CreateReader<apollo::control::ControlCommand>(
+      "/apollo/control",
+      [this](const std::shared_ptr<apollo::control::ControlCommand> &xctrlcmd) {
+        this->onControl(xctrlcmd);
+      });
+
+  localization_writer_ =
+      node_->CreateWriter<LocalizationEstimate>(FLAGS_localization_topic);
+  chassis_writer_ = node_->CreateWriter<Chassis>(FLAGS_chassis_topic);
+  prediction_writer_ =
+      node_->CreateWriter<PredictionObstacles>(FLAGS_prediction_topic);
+
+  // Start timer to publish localization and chassis messages.
+  sim_control_timer_.reset(new cyber::Timer(
+      kSimControlIntervalMs, [this]() { this->RunOnce(); }, false));
+  sim_prediction_timer_.reset(new cyber::Timer(
+      kSimPredictionIntervalMs, [this]() { this->PublishDummyPrediction(); },
+      false));
+}
+
+void SimPerfectControl::Init(bool set_start_point,
+                             nlohmann::json start_point_attr,
+                             bool use_start_point_position) {
+  if (set_start_point && !FLAGS_use_navigation_mode) {
+    InitStartPoint(start_point_attr["start_velocity"],
+                   start_point_attr["start_acceleration"]);
+  }
+}
+
+void SimPerfectControl::InitStartPoint(double x, double y,
+                                       double start_velocity,
+                                       double start_acceleration) {
+  TrajectoryPoint point;
+  // Use the scenario start point as start point,
+  start_point_from_localization_ = false;
+  point.mutable_path_point()->set_x(x);
+  point.mutable_path_point()->set_y(y);
+  // z use default 0
+  point.mutable_path_point()->set_z(0);
+  double theta = 0.0;
+  double s = 0.0;
+  map_service_->GetPoseWithRegardToLane(x, y, &theta, &s);
+  point.mutable_path_point()->set_theta(theta);
+  point.set_v(start_velocity);
+  point.set_a(start_acceleration);
+  SetStartPoint(point);
+}
+
+void SimPerfectControl::ReSetPoinstion(double x, double y, double heading) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  TrajectoryPoint point;
+  point.mutable_path_point()->set_x(x);
+  point.mutable_path_point()->set_y(y);
+  // z use default 0
+  point.mutable_path_point()->set_z(0);
+  point.mutable_path_point()->set_theta(heading);
+  AINFO << "start point:" << point.DebugString();
+  SetStartPoint(point);
+  InternalReset();
+}
+
+void SimPerfectControl::InitStartPoint(double start_velocity,
+                                       double start_acceleration) {
+  TrajectoryPoint point;
+  // Use the latest localization position as start point,
+  // fall back to a dummy point from map
+  localization_reader_->Observe();
+  start_point_from_localization_ = false;
+  if (!localization_reader_->Empty()) {
+    const auto &localization = localization_reader_->GetLatestObserved();
+    const auto &pose = localization->pose();
+    if (map_service_->PointIsValid(pose.position().x(), pose.position().y())) {
+      point.mutable_path_point()->set_x(pose.position().x());
+      point.mutable_path_point()->set_y(pose.position().y());
+      point.mutable_path_point()->set_z(pose.position().z());
+      point.mutable_path_point()->set_theta(pose.heading());
+      point.set_v(
+          std::hypot(pose.linear_velocity().x(), pose.linear_velocity().y()));
+      // Calculates the dot product of acceleration and velocity. The sign
+      // of this projection indicates whether this is acceleration or
+      // deceleration.
+      double projection =
+          pose.linear_acceleration().x() * pose.linear_velocity().x() +
+          pose.linear_acceleration().y() * pose.linear_velocity().y();
+
+      // Calculates the magnitude of the acceleration. Negate the value if
+      // it is indeed a deceleration.
+      double magnitude = std::hypot(pose.linear_acceleration().x(),
+                                    pose.linear_acceleration().y());
+      point.set_a(std::signbit(projection) ? -magnitude : magnitude);
+      start_point_from_localization_ = true;
+    }
+  }
+  if (!start_point_from_localization_) {
+    apollo::common::PointENU start_point;
+    if (!map_service_->GetStartPoint(&start_point)) {
+      AWARN << "Failed to get a dummy start point from map!";
+      return;
+    }
+    point.mutable_path_point()->set_x(start_point.x());
+    point.mutable_path_point()->set_y(start_point.y());
+    point.mutable_path_point()->set_z(start_point.z());
+    double theta = 0.0;
+    double s = 0.0;
+    map_service_->GetPoseWithRegardToLane(start_point.x(), start_point.y(),
+                                          &theta, &s);
+    point.mutable_path_point()->set_theta(theta);
+    point.set_v(start_velocity);
+    point.set_a(start_acceleration);
+  }
+  SetStartPoint(point);
+}
+
+void SimPerfectControl::SetStartPoint(const TrajectoryPoint &start_point) {
+  next_point_ = start_point;
+  prev_point_index_ = next_point_index_ = 0;
+  received_planning_ = false;
+}
+
+void SimPerfectControl::Reset() {
+  std::lock_guard<std::mutex> lock(mutex_);
+  InternalReset();
+}
+
+void SimPerfectControl::Stop() {
+  if (enabled_) {
+    {
+      std::lock_guard<std::mutex> lock(timer_mutex_);
+      sim_control_timer_->Stop();
+      sim_prediction_timer_->Stop();
+    }
+    enabled_ = false;
+  }
+}
+
+void SimPerfectControl::InternalReset() {
+  current_routing_header_.Clear();
+  send_dummy_prediction_ = true;
+  ClearPlanning();
+}
+
+void SimPerfectControl::ClearPlanning() {
+  current_trajectory_->Clear();
+  received_planning_ = false;
+}
+
+void SimPerfectControl::OnReceiveNavigationInfo(
+    const std::shared_ptr<NavigationInfo> &navigation_info) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  if (!enabled_) {
+    return;
+  }
+  if (navigation_info->navigation_path_size() > 0) {
+    const auto &path = navigation_info->navigation_path(0).path();
+    if (path.path_point_size() > 0) {
+      adc_position_ = path.path_point(0);
+    }
+  }
+}
+
+void SimPerfectControl::onADCLoc(const std::shared_ptr<apollo::localization::LocalizationEstimate> &xloc){
+	std::lock_guard<std::mutex> lock(mutex_);
+	adcloc_ = xloc;
+	receiveadcloc = true;
+}
+
+void SimPerfectControl::OnPlanningCommand(
+    const std::shared_ptr<PlanningCommand> &planning_command) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  if (!enabled_) {
+    return;
+  }
+  // Avoid not sending prediction messages to planning after playing packets
+  // with obstacles
+  send_dummy_prediction_ = true;
+  current_routing_header_ = planning_command->header();
+  AINFO << "planning_command: " << planning_command->DebugString();
+
+  if (planning_command->lane_follow_command()
+          .routing_request()
+          .is_start_pose_set()) {
+    auto lane_follow_command = planning_command->mutable_lane_follow_command();
+    const auto &start_pose =
+        lane_follow_command->routing_request().waypoint(0).pose();
+    ClearPlanning();
+    TrajectoryPoint point;
+    point.mutable_path_point()->set_x(start_pose.x());
+    point.mutable_path_point()->set_y(start_pose.y());
+    point.set_a(next_point_.has_a() ? next_point_.a() : 0.0);
+    point.set_v(next_point_.has_v() ? next_point_.v() : 0.0);
+    double theta = 0.0;
+    double s = 0.0;
+
+    // Find the lane nearest to the start pose and get its heading as theta.
+    map_service_->GetPoseWithRegardToLane(start_pose.x(), start_pose.y(),
+                                          &theta, &s);
+
+    point.mutable_path_point()->set_theta(theta);
+    SetStartPoint(point);
+  }
+}
+
+void SimPerfectControl::onControl(
+    const std::shared_ptr<apollo::control::ControlCommand> &xCmd) {
+//  std::lock_guard<std::mutex> lock(mutex_);
+
+  std::lock_guard<std::mutex> lock(mutex_);
+
+ // std::cout<<"steer: "<<xCmd->steering_target()<<" acc: "<<xCmd->acceleration()<<" brake:"<<xCmd->brake()<<std::endl;
+  
+  fcmdsteer_ = xCmd->steering_target();
+  fcmdbrake_ = xCmd->brake();
+  fcmdacc_ = xCmd->throttle();
+}
+
+void SimPerfectControl::OnPredictionObstacles(
+    const std::shared_ptr<PredictionObstacles> &obstacles) {
+  std::lock_guard<std::mutex> lock(mutex_);
+
+  if (!enabled_) {
+    return;
+  }
+
+  send_dummy_prediction_ = obstacles->header().module_name() == "SimPrediction";
+}
+
+void SimPerfectControl::Start() {
+  std::lock_guard<std::mutex> lock(mutex_);
+
+  if (!enabled_) {
+    // When there is no localization yet, Init(true) will use a
+    // dummy point from the current map as an arbitrary start.
+    // When localization is already available, we do not need to
+    // reset/override the start point.
+    localization_reader_->Observe();
+    Json start_point_attr({});
+    start_point_attr["start_velocity"] =
+        next_point_.has_v() ? next_point_.v() : 0.0;
+    start_point_attr["start_acceleration"] =
+        next_point_.has_a() ? next_point_.a() : 0.0;
+    Init(true, start_point_attr);
+    InternalReset();
+    {
+      std::lock_guard<std::mutex> lock(timer_mutex_);
+      sim_control_timer_->Start();
+      sim_prediction_timer_->Start();
+    }
+    enabled_ = true;
+  }
+}
+
+void SimPerfectControl::Start(double x, double y,double v , double a ) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  if (!enabled_) {
+    // Do not use localization info. use scenario start point to init start
+    // point.
+    InitStartPoint(x, y, v, a);
+    InternalReset();
+    sim_control_timer_->Start();
+    sim_prediction_timer_->Start();
+    enabled_ = true;
+  }
+}
+
+void SimPerfectControl::OnPlanning(
+    const std::shared_ptr<ADCTrajectory> &trajectory) {
+  std::lock_guard<std::mutex> lock(mutex_);
+
+  if (!enabled_) {
+    return;
+  }
+
+  // Reset current trajectory and the indices upon receiving a new trajectory.
+  // The routing SimPerfectControl owns must match with the one Planning has.
+  if (IsSameHeader(trajectory->routing_header(), current_routing_header_)) {
+    current_trajectory_ = trajectory;
+    prev_point_index_ = 0;
+    next_point_index_ = 0;
+    received_planning_ = true;
+  } else {
+    ClearPlanning();
+  }
+}
+
+void SimPerfectControl::Freeze() {
+  next_point_.set_v(0.0);
+  next_point_.set_a(0.0);
+  prev_point_ = next_point_;
+}
+
+void SimPerfectControl::RunOnce() {
+  std::lock_guard<std::mutex> lock(mutex_);
+
+  TrajectoryPoint trajectory_point;
+  Chassis::GearPosition gear_position;
+  
+
+
+  
+  if (!PerfectControlModel(&trajectory_point, &gear_position)) {
+    if(receiveadcloc == false){
+    AERROR << "Failed to calculate next point with perfect control model";
+    return;
+    }
+  }
+  
+      PublishChassis(trajectory_point.v(), gear_position);
+  PublishLocalization(trajectory_point);
+  
+
+
+
+}
+
+bool SimPerfectControl::PerfectControlModel(
+    TrajectoryPoint *point, Chassis::GearPosition *gear_position) {
+  // Result of the interpolation.
+  auto current_time = Clock::NowInSeconds();
+  const auto &trajectory = current_trajectory_->trajectory_point();
+  *gear_position = current_trajectory_->gear();
+  
+//  adclog1("run perfect control model.");
+
+  if (!received_planning_) {
+    prev_point_ = next_point_;
+  } else {
+    if (current_trajectory_->estop().is_estop() ||
+        next_point_index_ >= trajectory.size()) {
+      // Freeze the car when there's an estop or the current trajectory has
+      // been exhausted.
+      Freeze();
+    } else {
+      // Determine the status of the car based on received planning message.
+      while (next_point_index_ < trajectory.size() &&
+             current_time > trajectory.Get(next_point_index_).relative_time() +
+                                current_trajectory_->header().timestamp_sec()) {
+        ++next_point_index_;
+      }
+
+      if (next_point_index_ >= trajectory.size()) {
+        next_point_index_ = trajectory.size() - 1;
+      }
+
+      if (next_point_index_ == 0) {
+        if(receiveadcloc == false)AERROR << "First trajectory point is a future point!";
+        return false;
+      }
+
+      prev_point_index_ = next_point_index_ - 1;
+
+      next_point_ = trajectory.Get(next_point_index_);
+      prev_point_ = trajectory.Get(prev_point_index_);
+    }
+  }
+
+  if (current_time > next_point_.relative_time() +
+                         current_trajectory_->header().timestamp_sec()) {
+    // Don't try to extrapolate if relative_time passes last point
+    *point = next_point_;
+  } else {
+    *point = InterpolateUsingLinearApproximation(
+        prev_point_, next_point_,
+        current_time - current_trajectory_->header().timestamp_sec());
+  }
+  
+  return true;
+}
+
+void SimPerfectControl::PublishChassis(double cur_speed,
+                                       Chassis::GearPosition gear_position) {
+  auto chassis = std::make_shared<Chassis>();
+  FillHeader("SimPerfectControl", chassis.get());
+
+  chassis->set_engine_started(true);
+  chassis->set_driving_mode(Chassis::COMPLETE_AUTO_DRIVE);
+  chassis->set_gear_location(gear_position);
+
+  chassis->set_speed_mps(static_cast<float>(cur_speed));
+  if (gear_position == canbus::Chassis::GEAR_REVERSE) {
+    chassis->set_speed_mps(-chassis->speed_mps());
+  }
+  
+  if((FLAGS_use_realveh == true) && (receiveadcloc)){
+	chassis->set_speed_mps(static_cast<float>(fNowVel));
+  }
+
+  chassis->set_throttle_percentage(fcmdacc_);
+  chassis->set_brake_percentage(fcmdbrake_);
+  chassis->set_steering_percentage(fcmdsteer_);
+
+  chassis_writer_->Write(chassis);
+  
+}
+
+void SimPerfectControl::PublishLocalization(const TrajectoryPoint &point) {
+  auto localization = std::make_shared<LocalizationEstimate>();
+  FillHeader("SimPerfectControl", localization.get());
+  
+  if((receiveadcloc))
+  {
+	  localization = adcloc_;
+	  localization_writer_->Write(localization);
+	  
+	  auto *pose = localization->mutable_pose();
+	  
+	  fNowVel = sqrt(pow(pose->mutable_linear_velocity()->x(),2)+pow(pose->mutable_linear_velocity()->y(),2));
+
+	 adc_position_.set_x(pose->position().x());
+     adc_position_.set_y(pose->position().y());
+     adc_position_.set_z(pose->position().z());
+	 return;
+  }
+  auto *pose = localization->mutable_pose();
+  auto prev = prev_point_.path_point();
+  auto next = next_point_.path_point();
+
+  // Set position  507530.95 4331929.85
+  pose->mutable_position()->set_x(point.path_point().x());
+  pose->mutable_position()->set_y(point.path_point().y());
+  pose->mutable_position()->set_z(point.path_point().z());
+  // Set orientation and heading
+  double cur_theta = point.path_point().theta();
+
+  if (FLAGS_use_navigation_mode) {
+    double flu_x = point.path_point().x();
+    double flu_y = point.path_point().y();
+
+    Eigen::Vector2d enu_coordinate =
+        common::math::RotateVector2d({flu_x, flu_y}, cur_theta);
+
+    enu_coordinate.x() += adc_position_.x();
+    enu_coordinate.y() += adc_position_.y();
+    pose->mutable_position()->set_x(enu_coordinate.x());
+    pose->mutable_position()->set_y(enu_coordinate.y());
+  }
+
+  Eigen::Quaternion<double> cur_orientation =
+      HeadingToQuaternion<double>(cur_theta);
+  pose->mutable_orientation()->set_qw(cur_orientation.w());
+  pose->mutable_orientation()->set_qx(cur_orientation.x());
+  pose->mutable_orientation()->set_qy(cur_orientation.y());
+  pose->mutable_orientation()->set_qz(cur_orientation.z());
+  pose->set_heading(cur_theta);
+
+  // Set linear_velocity
+  pose->mutable_linear_velocity()->set_x(std::cos(cur_theta) * point.v());
+  pose->mutable_linear_velocity()->set_y(std::sin(cur_theta) * point.v());
+  pose->mutable_linear_velocity()->set_z(0);
+
+  // Set angular_velocity in both map reference frame and vehicle reference
+  // frame
+  pose->mutable_angular_velocity()->set_x(0);
+  pose->mutable_angular_velocity()->set_y(0);
+  pose->mutable_angular_velocity()->set_z(point.v() *
+                                          point.path_point().kappa());
+
+  TransformToVRF(pose->angular_velocity(), pose->orientation(),
+                 pose->mutable_angular_velocity_vrf());
+
+  // Set linear_acceleration in both map reference frame and vehicle reference
+  // frame
+  auto *linear_acceleration = pose->mutable_linear_acceleration();
+  linear_acceleration->set_x(std::cos(cur_theta) * point.a());
+  linear_acceleration->set_y(std::sin(cur_theta) * point.a());
+  linear_acceleration->set_z(0);
+
+  TransformToVRF(pose->linear_acceleration(), pose->orientation(),
+                 pose->mutable_linear_acceleration_vrf());
+  localization_writer_->Write(localization);
+
+  adc_position_.set_x(pose->position().x());
+  adc_position_.set_y(pose->position().y());
+  adc_position_.set_z(pose->position().z());
+}
+
+void SimPerfectControl::PublishDummyPrediction() {
+	if(receiveadcloc)return;
+  auto prediction = std::make_shared<PredictionObstacles>();
+  {
+    std::lock_guard<std::mutex> lock(mutex_);
+    if (!send_dummy_prediction_) {
+      return;
+    }
+    FillHeader("SimPrediction", prediction.get());
+  }
+  prediction_writer_->Write(prediction);
+}
+
+}  // namespace dreamview
+}  // namespace apollo

+ 225 - 0
src/apollo/change2/sim_perfect_control.h

@@ -0,0 +1,225 @@
+/******************************************************************************
+ * 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.
+ *****************************************************************************/
+
+/**
+ * @file
+ */
+
+#pragma once
+
+#include <memory>
+
+#include "gtest/gtest_prod.h"
+
+#include "modules/common_msgs/localization_msgs/localization.pb.h"
+#include "modules/common_msgs/planning_msgs/navigation.pb.h"
+#include "modules/common_msgs/planning_msgs/planning.pb.h"
+#include "modules/common_msgs/planning_msgs/planning_command.pb.h"
+#include "modules/common_msgs/prediction_msgs/prediction_obstacle.pb.h"
+#include "modules/common_msgs/routing_msgs/routing.pb.h"
+#include "modules/common_msgs/control_msgs/control_cmd.pb.h"
+
+#include "cyber/cyber.h"
+#include "modules/dreamview/backend/common/dreamview_gflags.h"
+#include "modules/dreamview/backend/common/map_service/map_service.h"
+#include "modules/dreamview/backend/common/sim_control_manager/core/sim_control_base.h"
+
+/**
+ * @namespace apollo::dreamview
+ * @brief apollo::dreamview
+ */
+namespace apollo {
+namespace dreamview {
+
+/**
+ * @class SimPerfectControl
+ * @brief A module that simulates a 'perfect control' algorithm, which assumes
+ * an ideal world where the car can be perfectly placed wherever the planning
+ * asks it to be, with the expected speed, acceleration, etc.
+ */
+class SimPerfectControl final : public SimControlBase {
+ public:
+  /**
+   * @brief Constructor of SimPerfectControl.
+   * @param map_service the pointer of MapService.
+   */
+  explicit SimPerfectControl(const MapService *map_service);
+
+  /**
+   * @brief setup callbacks and timer
+   * @param set_start_point initialize localization.
+   */
+  void Init(bool set_start_point, nlohmann::json start_point_attr,
+            bool use_start_point_position = false) override;
+
+  /**
+   * @brief Starts the timer to publish simulated localization and chassis
+   * messages.
+   */
+  void Start() override;
+
+  /**
+   * @brief Stops the timer.
+   */
+  void Stop() override;
+
+  /**
+   * @brief Set vehicle position.
+   */
+  void ReSetPoinstion(double x, double y, double heading) override;
+
+  /**
+   * @brief Resets the internal state.
+   */
+  void Reset() override;
+
+  void RunOnce() override;
+
+ private:
+  void OnPlanning(
+      const std::shared_ptr<apollo::planning::ADCTrajectory> &trajectory);
+  void OnPlanningCommand(
+      const std::shared_ptr<apollo::planning::PlanningCommand>
+          &planning_command);
+  void OnReceiveNavigationInfo(
+      const std::shared_ptr<apollo::relative_map::NavigationInfo>
+          &navigation_info);
+  void OnPredictionObstacles(
+      const std::shared_ptr<apollo::prediction::PredictionObstacles>
+          &obstacles);
+          
+  void onADCLoc(const std::shared_ptr<apollo::localization::LocalizationEstimate> &xloc);
+  
+  void onControl(
+    const std::shared_ptr<apollo::control::ControlCommand> &xCmd); 
+
+  /**
+   * @brief Predict the next trajectory point using perfect control model
+   */
+  bool PerfectControlModel(
+      apollo::common::TrajectoryPoint *point,
+      apollo::canbus::Chassis::GearPosition *gear_position);
+
+  void PublishChassis(double cur_speed,
+                      apollo::canbus::Chassis::GearPosition gear_position);
+
+  void PublishLocalization(const apollo::common::TrajectoryPoint &point);
+
+  void PublishDummyPrediction();
+
+  void InitTimerAndIO();
+
+  /**
+   * @brief Starts the timer to publish simulated localization and chassis
+   * messages. Designated Start point for scenario
+   */
+  void Start(double x, double y, double v = 0.0, double a = 0.0) override;
+
+  void InitStartPoint(double start_velocity, double start_acceleration);
+
+  // use scenario start point to init start point under the simulation
+  // condition.
+  void InitStartPoint(double x, double y, double start_velocity,
+                      double start_acceleration);
+
+  // Reset the start point, which can be a dummy point on the map, a current
+  // localization pose, or a start position received from the routing module.
+  void SetStartPoint(const apollo::common::TrajectoryPoint &point);
+
+  void Freeze();
+
+  void ClearPlanning();
+
+  void InternalReset();
+
+  const MapService *map_service_ = nullptr;
+
+  std::unique_ptr<cyber::Node> node_;
+
+  std::shared_ptr<cyber::Reader<apollo::localization::LocalizationEstimate>>
+      localization_reader_;
+  std::shared_ptr<cyber::Reader<apollo::planning::ADCTrajectory>>
+      planning_reader_;
+  std::shared_ptr<cyber::Reader<apollo::relative_map::NavigationInfo>>
+      navigation_reader_;
+  std::shared_ptr<cyber::Reader<apollo::prediction::PredictionObstacles>>
+      prediction_reader_;
+  std::shared_ptr<cyber::Reader<apollo::planning::PlanningCommand>>
+      planning_command_reader_;
+  std::shared_ptr<cyber::Writer<apollo::localization::LocalizationEstimate>>
+      localization_writer_;
+  std::shared_ptr<cyber::Writer<apollo::canbus::Chassis>> chassis_writer_;
+  std::shared_ptr<cyber::Writer<apollo::prediction::PredictionObstacles>>
+      prediction_writer_;
+      
+   std::shared_ptr<cyber::Reader<apollo::localization::LocalizationEstimate>>
+      localization_adc_reader_;
+      
+  std::shared_ptr<apollo::cyber::Reader<apollo::control::ControlCommand>>
+      control_command_reader_;
+
+  // The timer to publish simulated localization and chassis messages.
+  std::unique_ptr<cyber::Timer> sim_control_timer_;
+
+  // The timer to publish dummy prediction
+  std::unique_ptr<cyber::Timer> sim_prediction_timer_;
+
+  // Time interval of the timer, in milliseconds.
+  static constexpr double kSimControlIntervalMs = 10;
+  static constexpr double kSimPredictionIntervalMs = 100;
+
+  // The latest received planning trajectory.
+  std::shared_ptr<apollo::planning::ADCTrajectory> current_trajectory_;
+  // The index of the previous and next point with regard to the
+  // current_trajectory.
+  int prev_point_index_ = 0;
+  int next_point_index_ = 0;
+
+  // Whether there's a planning received after the most recent routing.
+  bool received_planning_ = false;
+  
+  std::shared_ptr<apollo::localization::LocalizationEstimate> adcloc_;
+  bool receiveadcloc = false;
+
+  // Whether start point is initialized from actual localization data
+  bool start_point_from_localization_ = false;
+
+  // Whether to send dummy predictions
+  bool send_dummy_prediction_ = true;
+
+  // The header of the routing planning is following.
+  apollo::common::Header current_routing_header_;
+
+  apollo::common::TrajectoryPoint prev_point_;
+  apollo::common::TrajectoryPoint next_point_;
+
+  common::PathPoint adc_position_;
+
+  // Linearize reader/timer callbacks and external operations.
+  std::mutex mutex_;
+  // Locks related to timer.
+  std::mutex timer_mutex_;
+  
+  double fcmdsteer_ = 0.0;
+  double fcmdbrake_ = 0.0;
+  double fcmdacc_  = 0.0;
+
+  FRIEND_TEST(SimControlTest, Test);
+  FRIEND_TEST(SimControlTest, TestDummyPrediction);
+};
+
+}  // namespace dreamview
+}  // namespace apollo

+ 23 - 2
src/apollo/code/pilot_apollo_bridge_gui/mainwindow.cpp

@@ -13,8 +13,11 @@ MainWindow::MainWindow(QWidget *parent)
     pilot_node = apollo::cyber::CreateNode("pilot_apollo_bridge_gui");
 
     mcmd_writer_ = pilot_node->CreateWriter<iv::apollo::apolloctrlcmd>("apcmd");
-    mgps_writer_ = pilot_node->CreateWriter<iv::gps::gpsimu>("adc_gps");
-    mobj_writer_ = pilot_node->CreateWriter<iv::lidar::objectarray>("adc_obj");
+    mgps_writer_ = pilot_node->CreateWriter<iv::gps::gpsimu>("/adc/gps");
+    mobj_writer_ = pilot_node->CreateWriter<iv::lidar::objectarray>("/adc/obj");
+    mcmd_reader_ = pilot_node->CreateReader<iv::apollo::apolloctrlcmd>("/adc/control",[this](const std::shared_ptr<iv::apollo::apolloctrlcmd>& cmd_ptr){
+        this->onControl(cmd_ptr);
+    });
 
     ModuleFun fungpsimu =std::bind(&MainWindow::ListenGPSIMU,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,std::placeholders::_4,std::placeholders::_5);
     mpagps = iv::modulecomm::RegisterRecvPlus("hcp2_gpsimu",fungpsimu);
@@ -22,6 +25,8 @@ MainWindow::MainWindow(QWidget *parent)
     ModuleFun funlidartrack =std::bind(&MainWindow::ListenLiarTrack,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,std::placeholders::_4,std::placeholders::_5);
     mpaobj = iv::modulecomm::RegisterRecvPlus("lidar_track",funlidartrack);
 
+    mpactrl = iv::modulecomm::RegisterSend("apolloctrlcmd",10000,1);
+
     mpthreadtest = new std::thread(&MainWindow::threadtest,this);
 
     ui->pushButton_StartApollo->setEnabled(true);
@@ -62,6 +67,7 @@ MainWindow::~MainWindow()
     mbtestrun = false;
     mpthreadtest->join();
 
+    iv::modulecomm::Unregister(mpactrl);
     iv::modulecomm::Unregister(mpaobj);
     iv::modulecomm::Unregister(mpagps);
 
@@ -207,6 +213,9 @@ void MainWindow::ListenGPSIMU(const char * strdata,const unsigned int nSize,cons
 
 void MainWindow::ListenLiarTrack(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname){
 //  iv::lidar::objectarray xobjarray;
+    (void)index;
+    (void)dt;
+    (void)strmemname;
 
 //  std::cout<<" recv lidar track."<<std::endl;
   auto obj_ptr = std::make_shared<iv::lidar::objectarray>();
@@ -217,3 +226,15 @@ void MainWindow::ListenLiarTrack(const char * strdata,const unsigned int nSize,c
   }
   mobj_writer_->Write(obj_ptr);
 }
+
+void MainWindow::onControl(const std::shared_ptr<iv::apollo::apolloctrlcmd> &xCmd)
+{
+    int nbytesize = (int)xCmd->ByteSize();
+    std::shared_ptr<char> pstr_ptr = std::shared_ptr<char>(new char[nbytesize]);
+    if(!xCmd->SerializeToArray(pstr_ptr.get(),nbytesize))
+    {
+        std::cout<<" send ctrlcmd Serialize Fail. "<<std::endl;
+        return;
+    }
+    iv::modulecomm::ModuleSendMsg(mpactrl,pstr_ptr.get(),nbytesize);
+}

+ 5 - 0
src/apollo/code/pilot_apollo_bridge_gui/mainwindow.h

@@ -46,6 +46,8 @@ private:
     void ListenGPSIMU(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname);
     void ListenLiarTrack(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname);
 
+    void onControl(const std::shared_ptr<iv::apollo::apolloctrlcmd> &xCmd);
+
 private:
     std::unique_ptr<apollo::cyber::Node> pilot_node;
 
@@ -53,6 +55,8 @@ private:
     bool mbtestrun = true;
 
     std::shared_ptr<apollo::cyber::Writer<iv::apollo::apolloctrlcmd>> mcmd_writer_ = nullptr;
+    std::shared_ptr<apollo::cyber::Reader<iv::apollo::apolloctrlcmd>> mcmd_reader_ = nullptr;
+
 
     std::shared_ptr<apollo::cyber::Writer<iv::gps::gpsimu>> mgps_writer_ = nullptr;
     std::shared_ptr<apollo::cyber::Writer<iv::lidar::objectarray>> mobj_writer_ = nullptr;
@@ -72,6 +76,7 @@ private:
 
     void * mpagps;
     void * mpaobj;
+    void * mpactrl;