sim_perfect_control.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. /******************************************************************************
  2. * Copyright 2017 The Apollo Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *****************************************************************************/
  16. #include "modules/dreamview/backend/common/sim_control_manager/dynamic_model/perfect_control/sim_perfect_control.h"
  17. #include "cyber/common/file.h"
  18. #include "cyber/time/clock.h"
  19. #include "modules/common/adapters/adapter_gflags.h"
  20. #include "modules/common/math/linear_interpolation.h"
  21. #include "modules/common/math/math_utils.h"
  22. #include "modules/common/math/quaternion.h"
  23. #include "modules/common/util/message_util.h"
  24. #include "modules/common/util/util.h"
  25. namespace apollo {
  26. namespace dreamview {
  27. using apollo::canbus::Chassis;
  28. using apollo::common::Header;
  29. using apollo::common::Point3D;
  30. using apollo::common::Quaternion;
  31. using apollo::common::TrajectoryPoint;
  32. using apollo::common::math::HeadingToQuaternion;
  33. using apollo::common::math::InterpolateUsingLinearApproximation;
  34. using apollo::common::math::InverseQuaternionRotate;
  35. using apollo::common::util::FillHeader;
  36. using apollo::cyber::Clock;
  37. using apollo::localization::LocalizationEstimate;
  38. using apollo::planning::ADCTrajectory;
  39. using apollo::planning::PlanningCommand;
  40. using apollo::prediction::PredictionObstacles;
  41. using apollo::relative_map::NavigationInfo;
  42. using Json = nlohmann::json;
  43. namespace {
  44. void TransformToVRF(const Point3D &point_mrf, const Quaternion &orientation,
  45. Point3D *point_vrf) {
  46. Eigen::Vector3d v_mrf(point_mrf.x(), point_mrf.y(), point_mrf.z());
  47. auto v_vrf = InverseQuaternionRotate(orientation, v_mrf);
  48. point_vrf->set_x(v_vrf.x());
  49. point_vrf->set_y(v_vrf.y());
  50. point_vrf->set_z(v_vrf.z());
  51. }
  52. bool IsSameHeader(const Header &lhs, const Header &rhs) {
  53. return lhs.sequence_num() == rhs.sequence_num() &&
  54. lhs.timestamp_sec() == rhs.timestamp_sec();
  55. }
  56. } // namespace
  57. SimPerfectControl::SimPerfectControl(const MapService *map_service)
  58. : SimControlBase(),
  59. map_service_(map_service),
  60. node_(cyber::CreateNode("sim_perfect_control")),
  61. current_trajectory_(std::make_shared<ADCTrajectory>()) {
  62. InitTimerAndIO();
  63. }
  64. void SimPerfectControl::InitTimerAndIO() {
  65. localization_reader_ =
  66. node_->CreateReader<LocalizationEstimate>(FLAGS_localization_topic);
  67. planning_reader_ = node_->CreateReader<ADCTrajectory>(
  68. FLAGS_planning_trajectory_topic,
  69. [this](const std::shared_ptr<ADCTrajectory> &trajectory) {
  70. this->OnPlanning(trajectory);
  71. });
  72. planning_command_reader_ = node_->CreateReader<PlanningCommand>(
  73. FLAGS_planning_command,
  74. [this](const std::shared_ptr<PlanningCommand> &planning_command) {
  75. this->OnPlanningCommand(planning_command);
  76. });
  77. navigation_reader_ = node_->CreateReader<NavigationInfo>(
  78. FLAGS_navigation_topic,
  79. [this](const std::shared_ptr<NavigationInfo> &navigation_info) {
  80. this->OnReceiveNavigationInfo(navigation_info);
  81. });
  82. prediction_reader_ = node_->CreateReader<PredictionObstacles>(
  83. FLAGS_prediction_topic,
  84. [this](const std::shared_ptr<PredictionObstacles> &obstacles) {
  85. this->OnPredictionObstacles(obstacles);
  86. });
  87. localization_writer_ =
  88. node_->CreateWriter<LocalizationEstimate>(FLAGS_localization_topic);
  89. chassis_writer_ = node_->CreateWriter<Chassis>(FLAGS_chassis_topic);
  90. prediction_writer_ =
  91. node_->CreateWriter<PredictionObstacles>(FLAGS_prediction_topic);
  92. //*********增加实际定位消息监听
  93. localization_adc_reader_ = node_->CreateReader<LocalizationEstimate>(
  94. "/apollo/localization/adcpose",
  95. [this](const std::shared_ptr<LocalizationEstimate> &xloc) {
  96. this->onADCLoc(xloc);
  97. });
  98. //*********完成本段
  99. // Start timer to publish localization and chassis messages.
  100. sim_control_timer_.reset(new cyber::Timer(
  101. kSimControlIntervalMs, [this]() { this->RunOnce(); }, false));
  102. sim_prediction_timer_.reset(new cyber::Timer(
  103. kSimPredictionIntervalMs, [this]() { this->PublishDummyPrediction(); },
  104. false));
  105. }
  106. void SimPerfectControl::Init(bool set_start_point,
  107. nlohmann::json start_point_attr,
  108. bool use_start_point_position) {
  109. if (set_start_point && !FLAGS_use_navigation_mode) {
  110. InitStartPoint(start_point_attr["start_velocity"],
  111. start_point_attr["start_acceleration"]);
  112. }
  113. }
  114. void SimPerfectControl::InitStartPoint(double x, double y,
  115. double start_velocity,
  116. double start_acceleration) {
  117. TrajectoryPoint point;
  118. // Use the scenario start point as start point,
  119. start_point_from_localization_ = false;
  120. point.mutable_path_point()->set_x(x);
  121. point.mutable_path_point()->set_y(y);
  122. // z use default 0
  123. point.mutable_path_point()->set_z(0);
  124. double theta = 0.0;
  125. double s = 0.0;
  126. map_service_->GetPoseWithRegardToLane(x, y, &theta, &s);
  127. point.mutable_path_point()->set_theta(theta);
  128. point.set_v(start_velocity);
  129. point.set_a(start_acceleration);
  130. SetStartPoint(point);
  131. }
  132. void SimPerfectControl::ReSetPoinstion(double x, double y, double heading) {
  133. std::lock_guard<std::mutex> lock(mutex_);
  134. TrajectoryPoint point;
  135. point.mutable_path_point()->set_x(x);
  136. point.mutable_path_point()->set_y(y);
  137. // z use default 0
  138. point.mutable_path_point()->set_z(0);
  139. point.mutable_path_point()->set_theta(heading);
  140. SetStartPoint(point);
  141. InternalReset();
  142. }
  143. void SimPerfectControl::InitStartPoint(double start_velocity,
  144. double start_acceleration) {
  145. TrajectoryPoint point;
  146. // Use the latest localization position as start point,
  147. // fall back to a dummy point from map
  148. localization_reader_->Observe();
  149. start_point_from_localization_ = false;
  150. if (!localization_reader_->Empty()) {
  151. const auto &localization = localization_reader_->GetLatestObserved();
  152. const auto &pose = localization->pose();
  153. if (map_service_->PointIsValid(pose.position().x(), pose.position().y())) {
  154. point.mutable_path_point()->set_x(pose.position().x());
  155. point.mutable_path_point()->set_y(pose.position().y());
  156. point.mutable_path_point()->set_z(pose.position().z());
  157. point.mutable_path_point()->set_theta(pose.heading());
  158. point.set_v(
  159. std::hypot(pose.linear_velocity().x(), pose.linear_velocity().y()));
  160. // Calculates the dot product of acceleration and velocity. The sign
  161. // of this projection indicates whether this is acceleration or
  162. // deceleration.
  163. double projection =
  164. pose.linear_acceleration().x() * pose.linear_velocity().x() +
  165. pose.linear_acceleration().y() * pose.linear_velocity().y();
  166. // Calculates the magnitude of the acceleration. Negate the value if
  167. // it is indeed a deceleration.
  168. double magnitude = std::hypot(pose.linear_acceleration().x(),
  169. pose.linear_acceleration().y());
  170. point.set_a(std::signbit(projection) ? -magnitude : magnitude);
  171. start_point_from_localization_ = true;
  172. }
  173. }
  174. if (!start_point_from_localization_) {
  175. apollo::common::PointENU start_point;
  176. if (!map_service_->GetStartPoint(&start_point)) {
  177. AWARN << "Failed to get a dummy start point from map!";
  178. return;
  179. }
  180. point.mutable_path_point()->set_x(start_point.x());
  181. point.mutable_path_point()->set_y(start_point.y());
  182. point.mutable_path_point()->set_z(start_point.z());
  183. double theta = 0.0;
  184. double s = 0.0;
  185. map_service_->GetPoseWithRegardToLane(start_point.x(), start_point.y(),
  186. &theta, &s);
  187. point.mutable_path_point()->set_theta(theta);
  188. point.set_v(start_velocity);
  189. point.set_a(start_acceleration);
  190. }
  191. SetStartPoint(point);
  192. }
  193. void SimPerfectControl::SetStartPoint(const TrajectoryPoint &start_point) {
  194. next_point_ = start_point;
  195. prev_point_index_ = next_point_index_ = 0;
  196. received_planning_ = false;
  197. }
  198. void SimPerfectControl::Reset() {
  199. std::lock_guard<std::mutex> lock(mutex_);
  200. InternalReset();
  201. }
  202. void SimPerfectControl::Stop() {
  203. if (enabled_) {
  204. {
  205. std::lock_guard<std::mutex> lock(timer_mutex_);
  206. sim_control_timer_->Stop();
  207. sim_prediction_timer_->Stop();
  208. }
  209. enabled_ = false;
  210. }
  211. }
  212. void SimPerfectControl::InternalReset() {
  213. current_routing_header_.Clear();
  214. send_dummy_prediction_ = true;
  215. ClearPlanning();
  216. }
  217. void SimPerfectControl::ClearPlanning() {
  218. current_trajectory_->Clear();
  219. received_planning_ = false;
  220. }
  221. void SimPerfectControl::OnReceiveNavigationInfo(
  222. const std::shared_ptr<NavigationInfo> &navigation_info) {
  223. std::lock_guard<std::mutex> lock(mutex_);
  224. if (!enabled_) {
  225. return;
  226. }
  227. if (navigation_info->navigation_path_size() > 0) {
  228. const auto &path = navigation_info->navigation_path(0).path();
  229. if (path.path_point_size() > 0) {
  230. adc_position_ = path.path_point(0);
  231. }
  232. }
  233. }
  234. void SimPerfectControl::OnPlanningCommand(
  235. const std::shared_ptr<PlanningCommand> &planning_command) {
  236. std::lock_guard<std::mutex> lock(mutex_);
  237. if (!enabled_) {
  238. return;
  239. }
  240. // Avoid not sending prediction messages to planning after playing packets
  241. // with obstacles
  242. send_dummy_prediction_ = true;
  243. current_routing_header_ = planning_command->header();
  244. AINFO << "planning_command: " << planning_command->DebugString();
  245. // if (planning_command->lane_follow_command()
  246. // .routing_request()
  247. // .is_start_pose_set()) {
  248. // auto lane_follow_command = planning_command->mutable_lane_follow_command();
  249. // const auto &start_pose =
  250. // lane_follow_command->routing_request().waypoint(0).pose();
  251. // ClearPlanning();
  252. // TrajectoryPoint point;
  253. // point.mutable_path_point()->set_x(start_pose.x());
  254. // point.mutable_path_point()->set_y(start_pose.y());
  255. // point.set_a(next_point_.has_a() ? next_point_.a() : 0.0);
  256. // point.set_v(next_point_.has_v() ? next_point_.v() : 0.0);
  257. // double theta = 0.0;
  258. // double s = 0.0;
  259. // // Find the lane nearest to the start pose and get its heading as theta.
  260. // map_service_->GetPoseWithRegardToLane(start_pose.x(), start_pose.y(),
  261. // &theta, &s);
  262. // point.mutable_path_point()->set_theta(theta);
  263. // SetStartPoint(point);
  264. // }
  265. return;
  266. }
  267. void SimPerfectControl::OnPredictionObstacles(
  268. const std::shared_ptr<PredictionObstacles> &obstacles) {
  269. std::lock_guard<std::mutex> lock(mutex_);
  270. if (!enabled_) {
  271. return;
  272. }
  273. send_dummy_prediction_ = obstacles->header().module_name() == "SimPrediction";
  274. }
  275. void SimPerfectControl::Start() {
  276. std::lock_guard<std::mutex> lock(mutex_);
  277. if (!enabled_) {
  278. // When there is no localization yet, Init(true) will use a
  279. // dummy point from the current map as an arbitrary start.
  280. // When localization is already available, we do not need to
  281. // reset/override the start point.
  282. localization_reader_->Observe();
  283. Json start_point_attr({});
  284. start_point_attr["start_velocity"] =
  285. next_point_.has_v() ? next_point_.v() : 0.0;
  286. start_point_attr["start_acceleration"] =
  287. next_point_.has_a() ? next_point_.a() : 0.0;
  288. Init(true, start_point_attr);
  289. InternalReset();
  290. {
  291. std::lock_guard<std::mutex> lock(timer_mutex_);
  292. sim_control_timer_->Start();
  293. sim_prediction_timer_->Start();
  294. }
  295. enabled_ = true;
  296. }
  297. }
  298. void SimPerfectControl::Start(double x, double y, double v, double a) {
  299. std::lock_guard<std::mutex> lock(mutex_);
  300. if (!enabled_) {
  301. // Do not use localization info. use scenario start point to init start
  302. // point.
  303. InitStartPoint(x, y, v, a);
  304. InternalReset();
  305. sim_control_timer_->Start();
  306. sim_prediction_timer_->Start();
  307. enabled_ = true;
  308. }
  309. }
  310. void SimPerfectControl::OnPlanning(
  311. const std::shared_ptr<ADCTrajectory> &trajectory) {
  312. std::lock_guard<std::mutex> lock(mutex_);
  313. if (!enabled_) {
  314. return;
  315. }
  316. // Reset current trajectory and the indices upon receiving a new trajectory.
  317. // The routing SimPerfectControl owns must match with the one Planning has.
  318. if (IsSameHeader(trajectory->routing_header(), current_routing_header_)) {
  319. current_trajectory_ = trajectory;
  320. prev_point_index_ = 0;
  321. next_point_index_ = 0;
  322. received_planning_ = true;
  323. } else {
  324. ClearPlanning();
  325. }
  326. }
  327. void SimPerfectControl::Freeze() {
  328. next_point_.set_v(0.0);
  329. next_point_.set_a(0.0);
  330. prev_point_ = next_point_;
  331. }
  332. void SimPerfectControl::RunOnce() {
  333. std::lock_guard<std::mutex> lock(mutex_);
  334. TrajectoryPoint trajectory_point;
  335. Chassis::GearPosition gear_position;
  336. if (!PerfectControlModel(&trajectory_point, &gear_position)) {
  337. AERROR << "Failed to calculate next point with perfect control model";
  338. return;
  339. }
  340. PublishChassis(trajectory_point.v(), gear_position);
  341. PublishLocalization(trajectory_point);
  342. }
  343. bool SimPerfectControl::PerfectControlModel(
  344. TrajectoryPoint *point, Chassis::GearPosition *gear_position) {
  345. // Result of the interpolation.
  346. auto current_time = Clock::NowInSeconds();
  347. const auto &trajectory = current_trajectory_->trajectory_point();
  348. *gear_position = current_trajectory_->gear();
  349. if (!received_planning_) {
  350. prev_point_ = next_point_;
  351. } else {
  352. if (current_trajectory_->estop().is_estop()) {
  353. // Freeze the car when there's an estop or the current trajectory has
  354. // been exhausted.
  355. Freeze();
  356. } else if (next_point_index_ >= trajectory.size()) {
  357. prev_point_ = next_point_;
  358. } else {
  359. // Determine the status of the car based on received planning message.
  360. while (next_point_index_ < trajectory.size() &&
  361. current_time > trajectory.Get(next_point_index_).relative_time() +
  362. current_trajectory_->header().timestamp_sec()) {
  363. ++next_point_index_;
  364. }
  365. if (next_point_index_ >= trajectory.size()) {
  366. next_point_index_ = trajectory.size() - 1;
  367. }
  368. if (next_point_index_ == 0) {
  369. AERROR << "First trajectory point is a future point!";
  370. return false;
  371. }
  372. prev_point_index_ = next_point_index_ - 1;
  373. next_point_ = trajectory.Get(next_point_index_);
  374. prev_point_ = trajectory.Get(prev_point_index_);
  375. }
  376. }
  377. if (current_time > next_point_.relative_time() +
  378. current_trajectory_->header().timestamp_sec()) {
  379. // Don't try to extrapolate if relative_time passes last point
  380. *point = next_point_;
  381. } else {
  382. *point = InterpolateUsingLinearApproximation(
  383. prev_point_, next_point_,
  384. current_time - current_trajectory_->header().timestamp_sec());
  385. }
  386. return true;
  387. }
  388. void SimPerfectControl::PublishChassis(double cur_speed,
  389. Chassis::GearPosition gear_position) {
  390. auto chassis = std::make_shared<Chassis>();
  391. FillHeader("SimPerfectControl", chassis.get());
  392. chassis->set_engine_started(true);
  393. chassis->set_driving_mode(Chassis::COMPLETE_AUTO_DRIVE);
  394. chassis->set_gear_location(gear_position);
  395. chassis->set_speed_mps(static_cast<float>(cur_speed));
  396. if (gear_position == canbus::Chassis::GEAR_REVERSE) {
  397. chassis->set_speed_mps(-chassis->speed_mps());
  398. }
  399. chassis->set_throttle_percentage(0.0);
  400. chassis->set_brake_percentage(0.0);
  401. chassis_writer_->Write(chassis);
  402. }
  403. void SimPerfectControl::PublishLocalization(const TrajectoryPoint &point) {
  404. auto localization = std::make_shared<LocalizationEstimate>();
  405. FillHeader("SimPerfectControl", localization.get());
  406. //*********增加
  407. if((receiveadcloc))
  408. {
  409. localization = adcloc_;
  410. localization_writer_->Write(localization);
  411. auto *pose = localization->mutable_pose();
  412. fNowVel = sqrt(pow(pose->mutable_linear_velocity()->x(),2)+pow(pose->mutable_linear_velocity()->y(),2));
  413. adc_position_.set_x(pose->position().x());
  414. adc_position_.set_y(pose->position().y());
  415. adc_position_.set_z(pose->position().z());
  416. return;
  417. }
  418. //*********完成增加
  419. auto *pose = localization->mutable_pose();
  420. auto prev = prev_point_.path_point();
  421. auto next = next_point_.path_point();
  422. // Set position
  423. pose->mutable_position()->set_x(point.path_point().x());
  424. pose->mutable_position()->set_y(point.path_point().y());
  425. pose->mutable_position()->set_z(point.path_point().z());
  426. // Set orientation and heading
  427. double cur_theta = point.path_point().theta();
  428. if (FLAGS_use_navigation_mode) {
  429. double flu_x = point.path_point().x();
  430. double flu_y = point.path_point().y();
  431. Eigen::Vector2d enu_coordinate =
  432. common::math::RotateVector2d({flu_x, flu_y}, cur_theta);
  433. enu_coordinate.x() += adc_position_.x();
  434. enu_coordinate.y() += adc_position_.y();
  435. pose->mutable_position()->set_x(enu_coordinate.x());
  436. pose->mutable_position()->set_y(enu_coordinate.y());
  437. }
  438. Eigen::Quaternion<double> cur_orientation =
  439. HeadingToQuaternion<double>(cur_theta);
  440. pose->mutable_orientation()->set_qw(cur_orientation.w());
  441. pose->mutable_orientation()->set_qx(cur_orientation.x());
  442. pose->mutable_orientation()->set_qy(cur_orientation.y());
  443. pose->mutable_orientation()->set_qz(cur_orientation.z());
  444. pose->set_heading(cur_theta);
  445. // Set linear_velocity
  446. pose->mutable_linear_velocity()->set_x(std::cos(cur_theta) * point.v());
  447. pose->mutable_linear_velocity()->set_y(std::sin(cur_theta) * point.v());
  448. pose->mutable_linear_velocity()->set_z(0);
  449. // Set angular_velocity in both map reference frame and vehicle reference
  450. // frame
  451. pose->mutable_angular_velocity()->set_x(0);
  452. pose->mutable_angular_velocity()->set_y(0);
  453. pose->mutable_angular_velocity()->set_z(point.v() *
  454. point.path_point().kappa());
  455. TransformToVRF(pose->angular_velocity(), pose->orientation(),
  456. pose->mutable_angular_velocity_vrf());
  457. // Set linear_acceleration in both map reference frame and vehicle reference
  458. // frame
  459. auto *linear_acceleration = pose->mutable_linear_acceleration();
  460. linear_acceleration->set_x(std::cos(cur_theta) * point.a());
  461. linear_acceleration->set_y(std::sin(cur_theta) * point.a());
  462. linear_acceleration->set_z(0);
  463. TransformToVRF(pose->linear_acceleration(), pose->orientation(),
  464. pose->mutable_linear_acceleration_vrf());
  465. localization_writer_->Write(localization);
  466. adc_position_.set_x(pose->position().x());
  467. adc_position_.set_y(pose->position().y());
  468. adc_position_.set_z(pose->position().z());
  469. }
  470. void SimPerfectControl::PublishDummyPrediction() {
  471. auto prediction = std::make_shared<PredictionObstacles>();
  472. {
  473. //*********增加
  474. if(receiveadcloc)return;
  475. //*********完成增加
  476. std::lock_guard<std::mutex> lock(mutex_);
  477. if (!send_dummy_prediction_) {
  478. return;
  479. }
  480. FillHeader("SimPrediction", prediction.get());
  481. }
  482. prediction_writer_->Write(prediction);
  483. }
  484. //*********增加
  485. void SimPerfectControl::onADCLoc(const std::shared_ptr<apollo::localization::LocalizationEstimate> &xloc){
  486. std::lock_guard<std::mutex> lock(mutex_);
  487. adcloc_ = xloc;
  488. receiveadcloc = true;
  489. }
  490. //*********完成增加
  491. } // namespace dreamview
  492. } // namespace apollo