Apollo 11.0
自动驾驶开放平台
navigator.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 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
17#include <fstream>
18#include <string>
19#include <thread>
20#include <vector>
21
22#include "nlohmann/json.hpp"
23
24#include "cyber/common/file.h"
25#include "cyber/common/log.h"
26#include "cyber/cyber.h"
27#include "cyber/time/rate.h"
31#include "modules/common_msgs/planning_msgs/navigation.pb.h"
32#include "modules/map/relative_map/proto/navigator_config.pb.h"
33
38using nlohmann::json;
39
41 int argc, char** argv, std::vector<std::string>* navigation_line_filenames);
42bool GetNavigationPathFromFile(const std::string& filename,
43 const NavigatorConfig& navigator_config,
44 NavigationPath* navigation_path);
45void CheckConfig(const apollo::relative_map::NavigatorConfig& navigator_config);
46
47int main(int argc, char** argv) {
48 google::ParseCommandLineFlags(&argc, &argv, true);
49 // Init the cyber framework
50 apollo::cyber::Init(argv[0]);
51 FLAGS_alsologtostderr = true;
52
53 NavigatorConfig navigator_config;
54 AINFO << "The navigator configuration filename is: "
55 << FLAGS_navigator_config_filename;
56 if (!apollo::cyber::common::GetProtoFromFile(FLAGS_navigator_config_filename,
57 &navigator_config)) {
58 AERROR << "Failed to parse " << FLAGS_navigator_config_filename;
59 return -1;
60 }
61 CheckConfig(navigator_config);
62
63 std::vector<std::string> navigation_line_filenames;
64 if (!ParseNavigationLineFileNames(argc, argv, &navigation_line_filenames)) {
65 AERROR << "Failed to get navigation file names.";
66 AINFO << "Usage: \n"
67 << "\t" << argv[0]
68 << " navigation_filename_1 navigation_filename_2 ...\n"
69 << "For example: \n"
70 << "\t" << argv[0]
71 << " left.txt.smoothed right.txt.smoothed middle.txt.smoothed";
72 return -1;
73 }
74
75 ADEBUG << "The flag \"navigator_down_sample\" is: "
76 << navigator_config.enable_navigator_downsample();
77
78 NavigationInfo navigation_info;
79 int i = 0;
80 for (const std::string& filename : navigation_line_filenames) {
81 auto* navigation_path = navigation_info.add_navigation_path();
82 if (!GetNavigationPathFromFile(filename, navigator_config,
83 navigation_path)) {
84 AWARN << "Failed to load file: " << filename;
85 continue;
86 }
87 AINFO << "The file: " << filename + " is processed ";
88 navigation_path->set_path_priority(i);
89 navigation_path->mutable_path()->set_name("Navigation path " + i);
90 ++i;
91 }
92 if (navigation_info.navigation_path_size() < 1) {
93 AERROR << "No navigation information is fetched.";
94 return -1;
95 }
96
97 std::shared_ptr<apollo::cyber::Node> node(
98 apollo::cyber::CreateNode("navigation_info"));
99 auto writer = node->CreateWriter<apollo::relative_map::NavigationInfo>(
100 FLAGS_navigation_topic);
101
102 // In theory, the message only needs to be sent once. Considering the problems
103 // such as the network delay, We send it several times to ensure that the data
104 // is sent successfully.
105 Rate rate(1.0);
106 static constexpr int kTransNum = 3;
107 int trans_num = 0;
108 while (apollo::cyber::OK()) {
109 if (trans_num > kTransNum) {
110 break;
111 }
112 apollo::common::util::FillHeader(node->Name(), &navigation_info);
113 writer->Write(navigation_info);
114 ADEBUG << "Sending navigation info:" << navigation_info.DebugString();
115 rate.Sleep();
116 ++trans_num;
117 }
118
119 return 0;
120}
121
123 int argc, char** argv,
124 std::vector<std::string>* navigation_line_filenames) {
125 CHECK_NOTNULL(navigation_line_filenames);
126 bool initialized = false;
127 if (argc > 1) {
128 try {
129 navigation_line_filenames->resize(argc - 1);
130 for (int i = 0; i < argc - 1; ++i) {
131 navigation_line_filenames->at(i) = argv[i + 1];
132 }
133 initialized = true;
134 } catch (const std::exception& e) {
135 AERROR << "Failed to get navigation line filenames: " << e.what();
136 initialized = false;
137 }
138 }
139
140 return initialized;
141}
142
143bool GetNavigationPathFromFile(const std::string& filename,
144 const NavigatorConfig& navigator_config,
145 NavigationPath* navigation_path) {
146 CHECK_NOTNULL(navigation_path);
147
148 std::ifstream ifs(filename, std::ios::in);
149 if (!ifs.is_open()) {
150 AERROR << "Failed to open " << filename;
151 return false;
152 }
153 std::string line_str;
154 double last_sampled_s = std::numeric_limits<double>::min();
155 double current_sampled_s = 0.0;
156 double diff_s = 0.0;
157 double current_kappa = 0.0;
158 int original_points_num = 0;
159 int down_sampled_points_num = 0;
160 const auto& sample_param = navigator_config.sample_param();
161 while (std::getline(ifs, line_str)) {
162 try {
163 auto json_obj = json::parse(line_str);
164 current_sampled_s = json_obj["s"];
165 current_kappa = json_obj["kappa"];
166 diff_s = std::fabs(current_sampled_s - last_sampled_s);
167 bool not_down_sampling =
168 navigator_config.enable_navigator_downsample()
169 ? diff_s >= sample_param.straight_sample_interval() ||
170 (diff_s >= sample_param.small_kappa_sample_interval() &&
171 std::fabs(current_kappa) > sample_param.small_kappa()) ||
172 (diff_s >= sample_param.middle_kappa_sample_interval() &&
173 std::fabs(current_kappa) > sample_param.middle_kappa()) ||
174 (diff_s >= sample_param.large_kappa_sample_interval() &&
175 std::fabs(current_kappa) > sample_param.large_kappa())
176 : true;
177 // Add a condition: !navigation_path->has_path() to keep the first point
178 // when down_sampling
179 if (not_down_sampling || !navigation_path->has_path()) {
180 last_sampled_s = current_sampled_s;
181 auto* point = navigation_path->mutable_path()->add_path_point();
182 point->set_x(json_obj["x"]);
183 point->set_y(json_obj["y"]);
184 point->set_s(current_sampled_s);
185 point->set_theta(json_obj["theta"]);
186 point->set_kappa(current_kappa);
187 point->set_dkappa(json_obj["dkappa"]);
188 ++down_sampled_points_num;
189 ADEBUG << "down_sample_x: " << json_obj["x"]
190 << ", down_sample_y: " << json_obj["y"];
191 }
192 ++original_points_num;
193 } catch (const std::exception& e) {
194 AERROR << "Failed to parse JSON data: " << e.what();
195 return false;
196 }
197 }
198 AINFO << "The number of original points is: " << original_points_num
199 << " and the number of down sampled points is: "
200 << down_sampled_points_num << " in the file: " << filename;
201 return true;
202}
203
205 const apollo::relative_map::NavigatorConfig& navigator_config) {
206 ACHECK(navigator_config.has_sample_param());
207 const auto& sample_param = navigator_config.sample_param();
208 ACHECK(sample_param.has_straight_sample_interval());
209 ACHECK(sample_param.has_small_kappa_sample_interval());
210 ACHECK(sample_param.has_middle_kappa_sample_interval());
211 ACHECK(sample_param.has_large_kappa_sample_interval());
212 ACHECK(sample_param.has_small_kappa());
213 ACHECK(sample_param.has_middle_kappa());
214 ACHECK(sample_param.has_large_kappa());
215}
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
bool ParseNavigationLineFileNames(int argc, char **argv, std::vector< std::string > *navigation_line_filenames)
Definition navigator.cc:122
int main(int argc, char **argv)
Definition navigator.cc:47
void CheckConfig(const apollo::relative_map::NavigatorConfig &navigator_config)
Definition navigator.cc:204
bool GetNavigationPathFromFile(const std::string &filename, const NavigatorConfig &navigator_config, NavigationPath *navigation_path)
Definition navigator.cc:143
Some string util functions.
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,...
Definition file.cc:132
bool Init(const char *binary_name, const std::string &dag_info)
Definition init.cc:99
bool OK()
Definition state.h:44
std::unique_ptr< Node > CreateNode(const std::string &node_name, const std::string &name_space)
Definition cyber.cc:33