Apollo 11.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 =
110 FLAGS_dynamic_model_package_library_path +
111 depend_model_package + "/" + dm_library_name;
112 SharedLibraryPtr shared_library = nullptr;
113 AINFO << "dm_library_name: " << dm_library_name;
114 AINFO << "dynamic_model_package_library_path: " << dynamic_model_package_library_path;
115
116 try {
117 // todo(@lijin):when to unload
118 shared_library =
119 SharedLibraryPtr(new SharedLibrary(dynamic_model_package_library_path));
120 create_t *create_dynamic_model =
121 reinterpret_cast<create_t *>(shared_library->GetSymbol("create"));
122 SimControlBase *dynamic_model_ptr =
123 create_dynamic_model(dm_dir_name, home_path_);
124 if (!dynamic_model_ptr) {
125 return false;
126 }
127 s_dynamic_model_map_[dynamic_model_name] = {};
128 s_dynamic_model_map_[dynamic_model_name].dynamic_model_name =
129 dynamic_model_name;
130 s_dynamic_model_map_[dynamic_model_name].dynamic_model_ptr =
131 dynamic_model_ptr;
132 s_dynamic_model_map_[dynamic_model_name].library_name = dm_library_name;
133 s_dynamic_model_map_[dynamic_model_name].depend_model_package =
134 dynamic_model_conf.depend_model_package();
135 auto iter = s_dm_lib_count_.find(dm_library_name);
136 if (iter == s_dm_lib_count_.end()) {
137 s_dm_lib_count_[dm_library_name] = 1;
138 } else {
139 s_dm_lib_count_[dm_library_name]++;
140 }
141 } catch (const LibraryLoadException &e) {
142 AERROR << "LibraryLoadException: " << e.what();
143 return false;
144 } catch (const LibraryAlreadyLoadedException &e) {
145 AERROR << "LibraryAlreadyLoadedException: " << e.what();
146 return false;
147 } catch (const SymbolNotFoundException &e) {
148 AERROR << "SymbolNotFoundException: " << e.what();
149 return false;
150 }
151 return true;
152}
153
154void DynamicModelFactory::GetDynamicModelPath(
155 const std::string &dynamic_model_name, std::string *path,
156 bool get_conf_json) {
157 CHECK_NOTNULL(path);
158 *path = dynamic_model_local_path_ + dynamic_model_name;
159 if (get_conf_json) {
160 *path = *path + "/dynamic_model.json";
161 }
162 return;
163}
164
165nlohmann::json DynamicModelFactory::RegisterDynamicModels() {
166 nlohmann::json result = {};
167 result["result"] = true;
168 result["loaded_dynamic_models"] = {};
169 if (!cyber::common::PathExists(dynamic_model_local_path_)) {
170 AERROR << "Failed to find DynamicModel!No dynamic model locally,Or do not "
171 "place it in correct location.";
172 } else {
173 DIR *directory = opendir(dynamic_model_local_path_.c_str());
174 if (directory == nullptr) {
175 AERROR << "Cannot open directory " << dynamic_model_local_path_;
176 } else {
177 struct dirent *file;
178 std::string dynamic_model_dir_name;
179 // std::string dynamic_model_package_library_path;
180 while ((file = readdir(directory)) != nullptr) {
181 // skip directory_path/. and directory_path/..
182 if (!strcmp(file->d_name, ".") || !strcmp(file->d_name, "..")) {
183 continue;
184 }
185 if (file->d_type != DT_DIR) {
186 continue;
187 }
188 dynamic_model_dir_name = file->d_name;
189 // avpid dumplicate register dynamic model
190 RegisterDynamicModel(dynamic_model_dir_name);
191 }
192 closedir(directory);
193 }
194 }
195
196 // c++ map's traversal order is different from the insertion order.
197 // To ensure that the default sim control is in the front,put it before other
198 // dynamic models.
199 result["loaded_dynamic_models"] = {FLAGS_sim_perfect_control};
200 for (auto iter = s_dynamic_model_map_.begin();
201 iter != s_dynamic_model_map_.end(); iter++) {
202 if (iter->first != FLAGS_sim_perfect_control) {
203 result["loaded_dynamic_models"].push_back(iter->first);
204 }
205 }
206 return result;
207}
208
209SimControlBase *DynamicModelFactory::GetModelType(
210 std::string dynamic_model_name) {
211 auto iter = s_dynamic_model_map_.find(dynamic_model_name);
212 if (iter == s_dynamic_model_map_.end()) {
213 AERROR << "Failed to get " << dynamic_model_name << " related pointer.";
214 return nullptr;
215 }
216 return iter->second.dynamic_model_ptr;
217}
218
219bool DynamicModelFactory::UnregisterDynamicModel(
220 const std::string &dynamic_model_name) {
221 auto iter = s_dynamic_model_map_.find(dynamic_model_name);
222 if (iter == s_dynamic_model_map_.end()) {
223 AERROR << "Failed to get " << dynamic_model_name << " related pointer.";
224 return true;
225 }
226 std::string library_name = iter->second.library_name;
227 s_dynamic_model_map_.erase(dynamic_model_name);
228 std::string dynamic_model_dir;
229 GetDynamicModelPath(dynamic_model_name, &dynamic_model_dir, false);
230 std::string command = "rm -fr " + dynamic_model_dir;
231 // use cyber::common::removeFiles do not support sub-directory
232 // use rmdir do not support not empty directory
233 if (std::system(command.data()) != 0) {
234 AERROR << "Failed to delete dynamic model directory for: "
235 << std::strerror(errno);
236 return false;
237 }
238 // delete related library if library is only used by this dynamic model
239 auto count_iter = s_dm_lib_count_.find(library_name);
240 std::string depend_model_package = iter->second.depend_model_package;
241 if (count_iter->second == 1) {
242 std::string lib_path =
243 home_path_ + FLAGS_dynamic_model_library_path + library_name;
245 // todo(chenhuanguang): confirm delete package command
246 // std::string remove_package_command = "";
247 // if (std::system(command.data()) != 0) {
248 // AERROR << "Failed to remove package: " << depend_model_package
249 // << " error: " << std::strerror(errno);
250 // return false;
251 // }
252 s_dm_lib_count_.erase(library_name);
253 } else {
254 s_dm_lib_count_[library_name]--;
255 }
256 auto dynamic_model_ptr = iter->second.dynamic_model_ptr;
257 delete dynamic_model_ptr;
258
259 return true;
260}
261
262} // namespace dreamview
263} // 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:495
bool PathExists(const std::string &path)
Check if the path exists.
Definition file.cc:195
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