Apollo 10.0
自动驾驶开放平台
dynamic_model_factory.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 *****************************************************************************/
17
18#include "modules/dreamview/backend/common/sim_control_manager/proto/dynamic_model_conf.pb.h"
19
26
27namespace apollo {
28namespace dreamview {
29
30using apollo::cyber::class_loader::LibraryAlreadyLoadedException;
31using apollo::cyber::class_loader::LibraryLoadException;
33using apollo::cyber::class_loader::SymbolNotFoundException;
34using ::std::string;
35using ::std::unordered_map;
36using SharedLibraryPtr = std::shared_ptr<SharedLibrary>;
37
44unordered_map<string, DynamicModelInfo> s_dynamic_model_map_;
45unordered_map<string, int> s_dm_lib_count_;
46
47DynamicModelFactory::DynamicModelFactory() : dynamic_model_local_path_("") {
48 home_path_ = cyber::common::GetEnv("HOME");
49 dynamic_model_local_path_ = home_path_ + FLAGS_resource_dynamic_model_path;
50 // init should register default sim control:SimPerfectControl
51 RegisterSimPerfectControl();
52}
53
54DynamicModelFactory::~DynamicModelFactory() {
55 for (auto iter = s_dynamic_model_map_.begin();
56 iter != s_dynamic_model_map_.end(); iter++) {
57 delete iter->second.dynamic_model_ptr;
58 iter->second.dynamic_model_ptr = nullptr;
59 }
60}
61
62void DynamicModelFactory::RegisterSimPerfectControl() {
63 // map_service当参数
64 if (s_dynamic_model_map_.find(FLAGS_sim_perfect_control) ==
66 // Avoid dumplicate register dynamic model which is already registered
67 s_dynamic_model_map_[FLAGS_sim_perfect_control] = {};
68 s_dynamic_model_map_[FLAGS_sim_perfect_control].dynamic_model_name =
69 FLAGS_sim_perfect_control;
70 s_dynamic_model_map_[FLAGS_sim_perfect_control].dynamic_model_ptr =
71 new SimPerfectControl(new MapService());
72 }
73}
74
75bool DynamicModelFactory::RegisterDynamicModel(const std::string &dm_dir_name) {
76 std::string dynamic_model_conf_json_path;
77 GetDynamicModelPath(dm_dir_name, &dynamic_model_conf_json_path, true);
78 if (!cyber::common::PathExists(dynamic_model_conf_json_path)) {
79 AERROR << "Failed to load Dynamic Model: " << dm_dir_name
80 << ". conf file is not exists!";
81 return false;
82 }
83 DynamicModelConf dynamic_model_conf;
84 if (!cyber::common::GetProtoFromJsonFile(dynamic_model_conf_json_path,
85 &dynamic_model_conf)) {
86 AERROR << "Unable to parse Dynamic model conf from file "
87 << dynamic_model_conf_json_path;
88 return false;
89 }
90 std::string dynamic_model_name = dynamic_model_conf.dynamic_model_name();
91 // get library name to load dm class
92 if (!dynamic_model_conf.has_library_name() ||
93 !dynamic_model_conf.has_dynamic_model_name() ||
94 !dynamic_model_conf.has_depend_model_package()) {
95 AERROR << "Missing required field!";
96 return false;
97 }
98 // if is already registered
99 auto iter = s_dynamic_model_map_.find(dynamic_model_name);
100 if (iter != s_dynamic_model_map_.end()) {
101 AERROR << "This dynamic model: " << dynamic_model_name
102 << " is already registered!";
103 return false;
104 }
105 std::string dm_library_name = dynamic_model_conf.library_name();
106 std::string depend_model_package = dynamic_model_conf.depend_model_package();
107 std::replace(depend_model_package.begin(), depend_model_package.end(), '-', '_');
108
109 std::string dynamic_model_package_library_path;
111 FLAGS_dynamic_model_package_library_path, "APOLLO_LIB_PATH",
112 &dynamic_model_package_library_path)) {
113 AERROR << "Failed to get dynamic model package library path: "
114 << FLAGS_dynamic_model_package_library_path;
115 return false;
116 }
117 dynamic_model_package_library_path +=
118 depend_model_package + "/" + dm_library_name;
119 SharedLibraryPtr shared_library = nullptr;
120 AINFO << "dm_library_name: " << dm_library_name;
121 AINFO << "dynamic_model_package_library_path: " << dynamic_model_package_library_path;
122
123 try {
124 // todo(@lijin):when to unload
125 shared_library =
126 SharedLibraryPtr(new SharedLibrary(dynamic_model_package_library_path));
127 create_t *create_dynamic_model =
128 reinterpret_cast<create_t *>(shared_library->GetSymbol("create"));
129 SimControlBase *dynamic_model_ptr =
130 create_dynamic_model(dm_dir_name, home_path_);
131 if (!dynamic_model_ptr) {
132 return false;
133 }
134 s_dynamic_model_map_[dynamic_model_name] = {};
135 s_dynamic_model_map_[dynamic_model_name].dynamic_model_name =
136 dynamic_model_name;
137 s_dynamic_model_map_[dynamic_model_name].dynamic_model_ptr =
138 dynamic_model_ptr;
139 s_dynamic_model_map_[dynamic_model_name].library_name = dm_library_name;
140 s_dynamic_model_map_[dynamic_model_name].depend_model_package =
141 dynamic_model_conf.depend_model_package();
142 auto iter = s_dm_lib_count_.find(dm_library_name);
143 if (iter == s_dm_lib_count_.end()) {
144 s_dm_lib_count_[dm_library_name] = 1;
145 } else {
146 s_dm_lib_count_[dm_library_name]++;
147 }
148 } catch (const LibraryLoadException &e) {
149 AERROR << "LibraryLoadException: " << e.what();
150 return false;
151 } catch (const LibraryAlreadyLoadedException &e) {
152 AERROR << "LibraryAlreadyLoadedException: " << e.what();
153 return false;
154 } catch (const SymbolNotFoundException &e) {
155 AERROR << "SymbolNotFoundException: " << e.what();
156 return false;
157 }
158 return true;
159}
160
161void DynamicModelFactory::GetDynamicModelPath(
162 const std::string &dynamic_model_name, std::string *path,
163 bool get_conf_json) {
164 CHECK_NOTNULL(path);
165 *path = dynamic_model_local_path_ + dynamic_model_name;
166 if (get_conf_json) {
167 *path = *path + "/dynamic_model.json";
168 }
169 return;
170}
171
172nlohmann::json DynamicModelFactory::RegisterDynamicModels() {
173 nlohmann::json result = {};
174 result["result"] = true;
175 result["loaded_dynamic_models"] = {};
176 if (!cyber::common::PathExists(dynamic_model_local_path_)) {
177 AERROR << "Failed to find DynamicModel!No dynamic model locally,Or do not "
178 "place it in correct location.";
179 } else {
180 DIR *directory = opendir(dynamic_model_local_path_.c_str());
181 if (directory == nullptr) {
182 AERROR << "Cannot open directory " << dynamic_model_local_path_;
183 } else {
184 struct dirent *file;
185 std::string dynamic_model_dir_name;
186 // std::string dynamic_model_package_library_path;
187 while ((file = readdir(directory)) != nullptr) {
188 // skip directory_path/. and directory_path/..
189 if (!strcmp(file->d_name, ".") || !strcmp(file->d_name, "..")) {
190 continue;
191 }
192 if (file->d_type != DT_DIR) {
193 continue;
194 }
195 dynamic_model_dir_name = file->d_name;
196 // avpid dumplicate register dynamic model
197 RegisterDynamicModel(dynamic_model_dir_name);
198 }
199 closedir(directory);
200 }
201 }
202
203 // c++ map's traversal order is different from the insertion order.
204 // To ensure that the default sim control is in the front,put it before other
205 // dynamic models.
206 result["loaded_dynamic_models"] = {FLAGS_sim_perfect_control};
207 for (auto iter = s_dynamic_model_map_.begin();
208 iter != s_dynamic_model_map_.end(); iter++) {
209 if (iter->first != FLAGS_sim_perfect_control) {
210 result["loaded_dynamic_models"].push_back(iter->first);
211 }
212 }
213 return result;
214}
215
216SimControlBase *DynamicModelFactory::GetModelType(
217 std::string dynamic_model_name) {
218 auto iter = s_dynamic_model_map_.find(dynamic_model_name);
219 if (iter == s_dynamic_model_map_.end()) {
220 AERROR << "Failed to get " << dynamic_model_name << " related pointer.";
221 return nullptr;
222 }
223 return iter->second.dynamic_model_ptr;
224}
225
226bool DynamicModelFactory::UnregisterDynamicModel(
227 const std::string &dynamic_model_name) {
228 auto iter = s_dynamic_model_map_.find(dynamic_model_name);
229 if (iter == s_dynamic_model_map_.end()) {
230 AERROR << "Failed to get " << dynamic_model_name << " related pointer.";
231 return true;
232 }
233 std::string library_name = iter->second.library_name;
234 s_dynamic_model_map_.erase(dynamic_model_name);
235 std::string dynamic_model_dir;
236 GetDynamicModelPath(dynamic_model_name, &dynamic_model_dir, false);
237 std::string command = "rm -fr " + dynamic_model_dir;
238 // use cyber::common::removeFiles do not support sub-directory
239 // use rmdir do not support not empty directory
240 if (std::system(command.data()) != 0) {
241 AERROR << "Failed to delete dynamic model directory for: "
242 << std::strerror(errno);
243 return false;
244 }
245 // delete related library if library is only used by this dynamic model
246 auto count_iter = s_dm_lib_count_.find(library_name);
247 std::string depend_model_package = iter->second.depend_model_package;
248 if (count_iter->second == 1) {
249 std::string lib_path =
250 home_path_ + FLAGS_dynamic_model_library_path + library_name;
252 // todo(chenhuanguang): confirm delete package command
253 // std::string remove_package_command = "";
254 // if (std::system(command.data()) != 0) {
255 // AERROR << "Failed to remove package: " << depend_model_package
256 // << " error: " << std::strerror(errno);
257 // return false;
258 // }
259 s_dm_lib_count_.erase(library_name);
260 } else {
261 s_dm_lib_count_[library_name]--;
262 }
263 auto dynamic_model_ptr = iter->second.dynamic_model_ptr;
264 delete dynamic_model_ptr;
265
266 return true;
267}
268
269} // namespace dreamview
270} // namespace apollo
Interface of simulated control algorithm
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
Some util functions.
bool DeleteFile(const string &filename)
Definition file.cc:509
bool PathExists(const std::string &path)
Check if the path exists.
Definition file.cc:195
bool GetFilePathWithEnv(const std::string &path, const std::string &env_var, std::string *file_path)
get file path, judgement priority:
Definition file.cc:436
bool GetProtoFromJsonFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the json file specified by the file_name as ascii representation of protobufs,...
Definition file.cc:149
std::string GetEnv(const std::string &var_name, const std::string &default_value="")
Definition environment.h:29
unordered_map< string, DynamicModelInfo > s_dynamic_model_map_
unordered_map< string, int > s_dm_lib_count_
std::shared_ptr< SharedLibrary > SharedLibraryPtr
SimControlBase * create_t(std::string dynamic_name, std::string home_path)
Get SimControl class
class register implement
Definition arena_queue.h:37