CARLA
 
载入中...
搜索中...
未找到
WalkerManager.cpp
浏览该文件的文档.
1// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
8
9#include "carla/Logging.h"
12#include "carla/client/World.h"
15#include "carla/rpc/Actor.h"
16
17namespace carla {
18namespace nav {
19
22
25
26 // 设置导航模块
28 _nav = nav;
29 }
30
31 // 设置模拟器的弱引用,以访问 API 函数
32 void WalkerManager::SetSimulator(std::weak_ptr<carla::client::detail::Simulator> simulator) {
33 _simulator = simulator;
34 }
35
36 // 创建新的行人路线
38 GetAllTrafficLightWaypoints();// 获取所有交通信号灯的路点
39
40 WalkerInfo info;
41 info.state = WALKER_IDLE;// 设置行人状态为闲置
42
43 // 保存行人信息
44 _walkers[id] = std::move(info);
45
46 return true;
47 }
48
49 // 移除行人路线
51 // 查找行人
52 auto it = _walkers.find(id);
53 if (it == _walkers.end())
54 return false;// 如果未找到行人,返回 false
55 _walkers.erase(it);// 移除行人
56
57 return true;
58 }
59
60 // 更新所有行人路线
61 bool WalkerManager::Update(double delta) {
62
63 // 检查所有行人
64 for (auto &it : _walkers) {
65
66 // 获取行人信息
67 WalkerInfo &info = it.second;
68
69 // 根据状态执行不同的操作
70 switch (info.state) {
71 case WALKER_IDLE:
72 break;// 闲置状态不做任何操作
73
74 case WALKER_WALKING:
75 {
76 // 获取目标点
77 carla::geom::Location &target = info.route[info.currentIndex].location;
78 // 获取当前位置信息
80 _nav->GetWalkerPosition(it.first, current);
81 // 计算与目标点的距离v
82 carla::geom::Vector3D dist(target.x - current.x, target.z - current.z, target.y - current.y);
83 if (dist.SquaredLength() <= 1) {// 判断是否到达目标点
84 info.state = WALKER_IN_EVENT;// 状态切换为在事件中
85 }
86 }
87 break;
88
89 case WALKER_IN_EVENT:
90 switch (ExecuteEvent(it.first, it.second, delta)) {
92 break;// 继续事件
94 // 进入下一个路径点
95 SetWalkerNextPoint(it.first);
96 break;
98 // 解锁改变路线的操作
99 SetWalkerRoute(it.first);
100 break;
101 }
102 break;
103
104 case WALKER_STOP:
105 info.state = WALKER_IDLE;// 停止后切换状态为闲置
106 break;
107 }
108 }
109
110 return true;
111 }
112
113 // 从当前位置信息设置新的路线
115 // 检查导航模块是否存在
116 if (_nav == nullptr)
117 return false;
118
119 // 设置一个新的随机目标点
120 carla::geom::Location location;
121 _nav->GetRandomLocation(location, nullptr);
122
123 // 设置行人的路线
124 return SetWalkerRoute(id, location);
125 }
126
127 // 从当前位置信息设置新的路线
129 // 检查导航模块是否存在
130 if (_nav == nullptr)
131 return false;
132
133 // 查找行人
134 auto it = _walkers.find(id);
135 if (it == _walkers.end())
136 return false;
137
138 // 获取行人信息
139 WalkerInfo &info = it->second;
140 std::vector<carla::geom::Location> path;
141 std::vector<unsigned char> area;// 存储区域信息
142
143 // 保存起点和终点
144 _nav->GetWalkerPosition(id, info.from);
145 info.to = to;
146 info.currentIndex = 0;
147 info.state = WALKER_IDLE;// 初始化状态为闲置
148
149 // 从导航中获取路径
150 _nav->GetAgentRoute(id, info.from, to, path, area);
151
152 // 创建每个路径点
153 info.route.clear();// 清空现有路线
154 info.route.reserve(path.size());// 预留空间
155 unsigned char previous_area = CARLA_AREA_SIDEWALK;// 记录前一个区域类型
156 for (unsigned int i=0; i<path.size(); ++i) {
157 // 获取区域类型
158 switch (area[i]) {
159 // 忽略侧道
161 info.route.emplace_back(WalkerEventIgnore(), std::move(path[i]), area[i]);
162 break;
163
164 // 在道路或人行道上停止并检查
165 case CARLA_AREA_ROAD:
167 // 仅当来自安全区域(人行道、草地或人行横道)时
168 if (previous_area != CARLA_AREA_CROSSWALK && previous_area != CARLA_AREA_ROAD)
169 info.route.emplace_back(WalkerEventStopAndCheck(60), std::move(path[i]), area[i]);
170 break;
171
172 default:
173 info.route.emplace_back(WalkerEventIgnore(), std::move(path[i]), area[i]);
174 }
175 previous_area = area[i];
176 }
177
178 // 分配下一个要走的点
180 return true;
181 }
182
183 // 设置路线中的下一个点
185 // check
186 if (_nav == nullptr)
187 return false;
188
189 // 搜索
190 auto it = _walkers.find(id);
191 if (it == _walkers.end())
192 return false;
193
194 // 获取行人信息
195 WalkerInfo &info = it->second;
196
197 // 前进到下一个点
198 ++info.currentIndex;
199
200 // 检查是否到达路线末尾
201 if (info.currentIndex < info.route.size()) {
202 // 改变状态为行走
203 info.state = WALKER_WALKING;
204 // 暂停行人的导航
205 _nav->PauseAgent(id, false);
206 _nav->SetWalkerDirectTarget(id, info.route[info.currentIndex].location);
207 } else {
208 // 改变状态为停止
209 info.state = WALKER_STOP;
210 _nav->PauseAgent(id, true);
211 // 需要从这里获取新的路线
212 SetWalkerRoute(id);
213 }
214
215 return true;
216 }
217
218 // 获取路线中的下一个点
220 // check
221 if (_nav == nullptr)
222 return false;
223
224 // search
225 auto it = _walkers.find(id);
226 if (it == _walkers.end())
227 return false;
228
229 // get it
230 WalkerInfo &info = it->second;
231
232 // check the end
233 if (info.currentIndex < info.route.size()) {
234 location = info.route[info.currentIndex].location;
235 return true;
236 } else {
237 return false;
238 }
239 }
240
242 // check
243 if (_nav == nullptr)
244 return false;
245
246 // search
247 auto it = _walkers.find(id);
248 if (it == _walkers.end())
249 return false;
250
251 // get it
252 WalkerInfo &info = it->second;
253
254 // 检查当前斑马线的结束位置
255 unsigned int pos = info.currentIndex;
256 while (pos < info.route.size()) {
257 if (info.route[pos].areaType != CARLA_AREA_CROSSWALK) {
258 location = info.route[pos].location;
259 return true;
260 }
261 ++pos;
262 }
263
264 return false;
265 }
266
268 // 获取当前事件的路线点
269 WalkerRoutePoint &rp = info.route[info.currentIndex];
270
271 // 构建访问者结构
272 WalkerEventVisitor visitor(this, id, delta);
273 // 运行事件
274 return boost::variant2::visit(visitor, rp.event);
275 }
276
277 // 获取所有交通灯的路标
279 static bool AlreadyCalculated = false;
280 if (AlreadyCalculated) return;
281
282 // 获取世界对象
283 carla::client::World world = _simulator.lock()->GetWorld();
284
285 _traffic_lights.clear();
286 std::vector<carla::rpc::Actor> actors = _simulator.lock()->GetAllTheActorsInTheEpisode();
287 for (auto actor : actors) {
288 carla::client::ActorSnapshot snapshot = _simulator.lock()->GetActorSnapshot(actor.id);
289 // 仅检查交通灯
290 if (actor.description.id == "traffic.traffic_light") {
291 // 获取交通灯对象
293 boost::static_pointer_cast<carla::client::TrafficLight>(world.GetActor(actor.id));
294 // 获取交通灯影响的路标
295 std::vector<SharedPtr<carla::client::Waypoint>> list = tl->GetStopWaypoints();
296 for (auto &way : list) {
297 _traffic_lights.emplace_back(tl, way->GetTransform().location);
298 }
299 }
300 }
301
302 AlreadyCalculated = true;// 标记为已计算
303 }
304
305
306 // 返回影响该位置的交通灯
308 carla::geom::Location UnrealPos,
309 float max_distance) {
310 float min_dist = std::numeric_limits<float>::infinity();
312 for (auto &&item : _traffic_lights) {
313 float dist = UnrealPos.DistanceSquared(item.second);
314 if (dist < min_dist) {
315 min_dist = dist;
316 actor = item.first;
317 }
318 }
319 // 如果距离超出限制,则拒绝该交通灯
320 if (max_distance < 0.0f || min_dist <= max_distance * max_distance) {
321 return actor;
322 } else {
324 }
325 }
326
327
328} // namespace nav
329} // namespace carla
SharedPtr< Actor > GetActor(ActorId id) const
根据id查找actor,如果没有找到则返回nullptr。 通过传入的ActorId参数,在当前模拟世界中查找对应的参与者对象,方便快速定位特定的实体, 比如查找某一辆特定编号的车辆或者某个行人等。
Definition World.cpp:106
auto DistanceSquared(const Location &loc) const
float SquaredLength() const
管理行人导航,使用 Recast & Detour 库进行低层计算。
Definition Navigation.h:86
bool GetWalkerPosition(ActorId id, carla::geom::Location &location)
获取行人的当前位置
bool SetWalkerDirectTarget(ActorId id, carla::geom::Location to)
void PauseAgent(ActorId id, bool pause)
将人群中的代理设置为暂停
bool GetRandomLocation(carla::geom::Location &location, dtQueryFilter *filter=nullptr) const
获取导航的随机位置
bool GetAgentRoute(ActorId id, carla::geom::Location from, carla::geom::Location to, std::vector< carla::geom::Location > &path, std::vector< unsigned char > &area)
bool RemoveWalker(ActorId id)
std::vector< std::pair< SharedPtr< carla::client::TrafficLight >, carla::geom::Location > > _traffic_lights
bool GetWalkerCrosswalkEnd(ActorId id, carla::geom::Location &location)
void SetSimulator(std::weak_ptr< carla::client::detail::Simulator > simulator)
EventResult ExecuteEvent(ActorId id, WalkerInfo &info, double delta)
bool Update(double delta)
bool GetWalkerNextPoint(ActorId id, carla::geom::Location &location)
bool SetWalkerNextPoint(ActorId id)
std::weak_ptr< carla::client::detail::Simulator > _simulator
std::unordered_map< ActorId, WalkerInfo > _walkers
SharedPtr< carla::client::TrafficLight > GetTrafficLightAffecting(carla::geom::Location UnrealPos, float max_distance=-1.0f)
void SetNav(Navigation *nav)
bool SetWalkerRoute(ActorId id)
@ CARLA_AREA_CROSSWALK
Definition Navigation.h:49
@ CARLA_AREA_SIDEWALK
Definition Navigation.h:48
@ CARLA_AREA_ROAD
Definition Navigation.h:50
EventResult
事件的结果
Definition WalkerEvent.h:43
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
boost::shared_ptr< T > SharedPtr
使用这个SharedPtr(boost::shared_ptr)以保持与boost::python的兼容性, 但未来如果可能的话,我们希望能为std::shared_ptr制作一个Python适配器。
Definition Memory.h:19
rpc::ActorId ActorId
Definition ActorId.h:26
暂停并检查附近车辆的事件
Definition WalkerEvent.h:68
unsigned int currentIndex
std::vector< WalkerRoutePoint > route
carla::geom::Location from
carla::geom::Location to