CARLA
 
载入中...
搜索中...
未找到
LightManager.cpp
浏览该文件的文档.
1// Copyright (c) 2020 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
10
11
12namespace carla {
13namespace client {
14
15 using LightGroup = rpc::LightState::LightGroup; // 定义 LightGroup类型,用于表示灯光组
16// 析构函数,清理灯光管理器资源
18 // 检查是否存在有效的场景实例
19 if(_episode.IsValid()) {
20 // 移除灯光相关的事件回调
21 _episode.Lock()->RemoveOnTickEvent(_on_light_update_register_id);
22 _episode.Lock()->RemoveLightUpdateChangeEvent(_on_light_update_register_id);
23 }
24 // 同步灯光状态至服务器并强制更新
26}
27
28// 设置当前场景实例并注册事件
30
31 _episode = episode; // 保存场景引用
32 // 注册在每帧更新时的回调函数
33 _on_tick_register_id = _episode.Lock()->RegisterOnTickEvent(
34 [&](const WorldSnapshot&) {
35 UpdateServerLightsState(); // 同步灯光状态到服务器
36 });
37
38 // 注册灯光更新事件的回调函数
39 _on_light_update_register_id = _episode.Lock()->RegisterLightUpdateChangeEvent(
40 [&](const WorldSnapshot& ) {
41 QueryLightsStateToServer(); // 查询灯光状态
42 ApplyChanges(); // 应用灯光的改变
43 });
44
45 QueryLightsStateToServer(); // 初始化时查询灯光状态
46}
47// 获取指定灯光组类型的所有灯光
48std::vector<Light> LightManager::GetAllLights(LightGroup type) const {
49 std::vector<Light> result;
50 // 遍历所有灯光状态
51 for(auto lights_state : _lights_state) {
52 LightGroup group = lights_state.second._group;
53 // 如果类型为None 或匹配指定类型,则添加到结果中
54 if((type == LightGroup::None) || (group == type)) {
55 auto it_light = _lights.find(lights_state.first);
56 result.push_back(it_light->second);
57 }
58 }
59
60 return result; // 返回符合条件的灯光
61}
62// 打开指定的灯光
63void LightManager::TurnOn(std::vector<Light>& lights) {
64 for(Light& light : lights) {
65 SetActive(light._id, true); // 设置灯光为激活状态
66 }
67}
68// 关闭指定的灯光
69void LightManager::TurnOff(std::vector<Light>& lights) {
70 for(Light& light : lights) {
71 SetActive(light._id, false); // 设置灯光为非激活状态
72 }
73}
74
75// 根据布尔值数组设置灯光激活状态
76void LightManager::SetActive(std::vector<Light>& lights, std::vector<bool>& active) {
77 size_t lights_to_update = (lights.size() < active.size()) ? lights.size() : active.size();
78 for(size_t i = 0; i < lights_to_update; i++) {
79 SetActive(lights[i]._id, active[i]); // 根据对应索引设置灯光状态
80 }
81}
82
83// 检查指定灯光是否为激活状态
84std::vector<bool> LightManager::IsActive(std::vector<Light>& lights) const {
85 std::vector<bool> result;
86 for(Light& light : lights) {
87 result.push_back( IsActive(light._id) ); // 查询每个灯光的激活状态
88 }
89 return result; // 返回激活状态列表
90}
91// 获取所有开启状态的灯光
92std::vector<Light> LightManager::GetTurnedOnLights(LightGroup type) const {
93 std::vector<Light> result;
94 // 遍历灯光状态
95 for(auto lights_state : _lights_state) {
96 LightState& state = lights_state.second;
97 LightGroup group = state._group;
98 // 检查类型匹配且灯光处于开启状态
99 if( (type == LightGroup::None || group == type) && state._active ) {
100 auto it_light = _lights.find(lights_state.first);
101 result.push_back(it_light->second);
102 }
103 }
104
105 return result; // 返回所有开启状态的灯光
106}
107// 获取所有关闭状态的灯光
108std::vector<Light> LightManager::GetTurnedOffLights(LightGroup type) const {
109 std::vector<Light> result;
110 // 遍历灯光状态
111 for(auto lights_state : _lights_state) {
112 LightState& state = lights_state.second;
113 LightGroup group = state._group;
114 // 检查类型匹配且灯光处于非关闭状态
115 if( (type == LightGroup::None || group == type) && !state._active ) {
116 auto it_light = _lights.find(lights_state.first);
117 result.push_back(it_light->second);
118 }
119 }
120
121 return result; // 返回所有关闭状态的灯光
122}
123
124// 设置多个灯光的相同颜色
125void LightManager::SetColor(std::vector<Light>& lights, Color color) {
126 // 遍历灯光列表,逐个设置颜色
127 for(Light& light : lights) {
128 SetColor(light._id, color); // 调用内部方法根据灯光ID设置颜色
129 }
130}
131
132// 设置多个灯光的不同颜色
133void LightManager::SetColor(std::vector<Light>& lights, std::vector<Color>& colors) {
134 // 确定需要更新的灯光数量,以灯光和颜色列表较短者为准
135 size_t lights_to_update = (lights.size() < colors.size()) ? lights.size() : colors.size();
136 // 遍历灯光和颜色列表,逐个设置颜色
137 for(size_t i = 0; i < lights_to_update; i++) {
138 SetColor(lights[i]._id, colors[i]); // 调用内部方法设置每个灯光的颜色
139 }
140}
141
142// 获取多个灯光的颜色
143std::vector<Color> LightManager::GetColor(std::vector<Light>& lights) const {
144 std::vector<Color> result; // 保存颜色结果的向量
145 for(Light& light : lights) {
146 result.push_back( GetColor(light._id) ); // 调用内部方法获取颜色
147 }
148 return result; // 返回所有灯光的颜色
149}
150
151// 设置多个灯光的相同亮度
152void LightManager::SetIntensity(std::vector<Light>& lights, float intensity) {
153 for(Light& light : lights) {
154 SetIntensity(light._id, intensity); // 调用内部方法设置亮度
155 }
156}
157
158//设置多个灯光的不同亮度
159void LightManager::SetIntensity(std::vector<Light>& lights, std::vector<float>& intensities) {
160 size_t lights_to_update = (lights.size() < intensities.size()) ? lights.size() : intensities.size();
161 for(size_t i = 0; i < lights_to_update; i++) {
162 SetIntensity(lights[i]._id, intensities[i]); // 根据灯光ID和亮度列表设置亮度
163 }
164}
165
166// 获取多个灯光的亮度
167std::vector<float> LightManager::GetIntensity(std::vector<Light>& lights) const {
168 std::vector<float> result; // 保存亮度结果的向量
169 for(Light& light : lights) {
170 result.push_back( GetIntensity(light._id) ); // 调用内部方法获取亮度
171 }
172 return result; // 返回所有灯光的亮度
173}
174
175// 设置多个灯光的相同分组
176void LightManager::SetLightGroup(std::vector<Light>& lights, LightGroup group) {
177 for(Light& light : lights) {
178 SetLightGroup(light._id, group); // 调用内部方法设置分组
179 }
180}
181
182// 设置多个灯光的不同分组
183void LightManager::SetLightGroup(std::vector<Light>& lights, std::vector<LightGroup>& groups) {
184 size_t lights_to_update = (lights.size() < groups.size()) ? lights.size() : groups.size();
185 for(size_t i = 0; i < lights_to_update; i++) {
186 SetLightGroup(lights[i]._id, groups[i]); // 根据灯光ID和分组列表设置分组
187 }
188}
189
190// 获取多个灯光的分组
191std::vector<LightGroup> LightManager::GetLightGroup(std::vector<Light>& lights) const {
192 std::vector<LightGroup> result; // 保存分组结果的向量
193 for(Light& light : lights) {
194 result.push_back( GetLightGroup(light._id) ); // 调用内部方法获取分组
195 }
196 return result; // 返回所有灯光的分组
197}
198
199// 设置多个灯光的相同状态
200void LightManager::SetLightState(std::vector<Light>& lights, LightState state) {
201 for(Light& light : lights) {
202 SetLightState(light._id, state); // 调用内部方法设置状态
203 }
204}
205
206// 设置多个灯光的不同状态
207void LightManager::SetLightState(std::vector<Light>& lights, std::vector<LightState>& states) {
208 size_t lights_to_update = (lights.size() < states.size()) ? lights.size() : states.size();
209 for(size_t i = 0; i < lights_to_update; i++) {
210 SetLightState(lights[i]._id, states[i]); // 根据灯光ID和状态列表设置状态
211 }
212}
213
214// 获取多个灯光的状态
215std::vector<LightState> LightManager::GetLightState(std::vector<Light>& lights) const {
216 std::vector<LightState> result; // 保存状态结果的向量
217 for(Light& light : lights) {
218 result.push_back( RetrieveLightState(light._id) ); // 调用内部方法获取状态
219 }
220 return result; // 返回所有灯光的状态
221}
222
224 // 返回指定灯光的颜色属性
225 return RetrieveLightState(id)._color;
226}
227
229 // 返回指定灯光的亮度属性
231}
232
234 // 返回指定灯光的完整状态信息
235 return RetrieveLightState(id);
236}
237
239 // 返回指定灯光的分组属性
240 return RetrieveLightState(id)._group;
241}
242
244 // 返回指定灯光是否处于激活状态
245 return RetrieveLightState(id)._active;
246}
247
248void LightManager::SetActive(LightId id, bool active) {
249 std::lock_guard<std::mutex> lock(_mutex); // 加锁以保护多线程访问
250 LightState& state = const_cast<LightState&>(RetrieveLightState(id)); // 获取灯光状态
251 state._active = active; // 更新激活状态
252 _lights_changes[id] = state; // 将更改记录到修改列表
253 _dirty = true; // 标记有更改
254}
255
257 std::lock_guard<std::mutex> lock(_mutex); // 加锁以保护多线程访问
258 LightState& state = const_cast<LightState&>(RetrieveLightState(id)); // 获取灯光状态
259 state._color = color; // 更新颜色属性
260 _lights_changes[id] = state; // 将更改记录到修改列表中
261 _dirty = true; // 标记有更改
262}
263
264void LightManager::SetIntensity(LightId id, float intensity) {
265 std::lock_guard<std::mutex> lock(_mutex); // 加锁以保护多线程访问
266 LightState& state = const_cast<LightState&>(RetrieveLightState(id)); // 获取灯光状态
267 state._intensity = intensity; // 更新亮度属性
268 _lights_changes[id] = state; // 将更改记录到修改列表
269 _dirty = true; // 标记有更改
270}
271
273 std::lock_guard<std::mutex> lock(_mutex); // 加锁以保护多线程访问
274 LightState& state = const_cast<LightState&>(RetrieveLightState(id)); // 获取灯光状态
275 state = new_state; //更新完整状态
276 _lights_changes[id] = state; // 将更改记录到修改列表
277 _dirty = true; // 标记有更改
278}
279
281 // 无需加锁设置指定灯光的完整状态信息,用于内部调用
282 LightState& state = const_cast<LightState&>(RetrieveLightState(id));
283 state = new_state; // 更新完整状态
284 _lights_changes[id] = state; // 将更改记录到修改列表
285}
286
288 std::lock_guard<std::mutex> lock(_mutex); // 加锁以保护多线程访问
289 LightState& state = const_cast<LightState&>(RetrieveLightState(id)); // 获取灯光状态
290 state._group = group; // 更新分组属性
291 _lights_changes[id] = state; // 将更改记录到修改列表
292 _dirty = true; // 标记有更改
293}
294
296 // 从存储中检索指定灯光的状态信息
297 auto it = _lights_state.find(id);
298 if(it == _lights_state.end()) {
299 carla::log_warning("Invalid light", id); // 记录无效灯光警告
300 return _state; // 返回默认状态
301 }
302 return it->second; // 返回找到的灯光状态
303}
304
306 std::lock_guard<std::mutex> lock(_mutex);
307 // 发送 blocking 查询到服务器以获取灯光状态
308 std::vector<rpc::LightState> lights_snapshot = _episode.Lock()->QueryLightsStateToServer();
309
310 // 更新本地灯光状态
311 SharedPtr<LightManager> lm = _episode.Lock()->GetLightManager();
312
313 for(const auto& it : lights_snapshot) {
314 _lights_state[it._id] = LightState(
315 it._intensity,
316 Color(it._color.r, it._color.g, it._color.b),
317 static_cast<LightState::LightGroup>(it._group),
318 it._active
319 );
320 // 如果灯光ID不在本地记录,则创建新灯光
321 if(_lights.find(it._id) == _lights.end())
322 {
323 _lights[it._id] = Light(lm, it._location, it._id);
324 }
325 }
326}
327
328void LightManager::UpdateServerLightsState(bool discard_client) {
329 // 创建锁以确保多线程环境下的互斥访问
330 std::lock_guard<std::mutex> lock(_mutex);
331 // 如果灯光状态存在变更
332 if(_dirty) {
333 // 定义一个存储灯光状态的消息列表
334 std::vector<rpc::LightState> message;
335 // 遍历所有变更的灯光状态
336 for(auto it : _lights_changes) {
337 // 在灯光映射中查找对应灯光
338 auto it_light = _lights.find(it.first);
339 if(it_light != _lights.end()) {
340 // 创建灯光状态对象,初始化位置、强度、分组、颜色、激活状态
341 rpc::LightState state(
342 it_light->second.GetLocation(),
343 it.second._intensity,
344 it.second._group,
345 rpc::Color(it.second._color.r, it.second._color.g, it.second._color.b),
346 it.second._active
347 );
348 state._id = it.first; // 设置灯光的唯一标识符
349 // 添加到命令
350 message.push_back(state);
351 }
352 }
353 // 更新服务器的灯光状态,传递消息列表和是否丢失客户端状态
354 _episode.Lock()->UpdateServerLightsState(message, discard_client);
355 // 清空本地灯光变更列表
356 _lights_changes.clear();
357 // 重置 _dirty 状态
358 _dirty = false;
359 }
360}
361
363 // 创建锁以确保多线程环境下的互斥访问
364 std::lock_guard<std::mutex> lock(_mutex);
365 // 遍历所有灯光变更项并应用每个更改
366 for(const auto& it : _lights_changes) {
367 // 调用内部方法,不加锁地设置灯光状态
368 SetLightStateNoLock(it.first, it.second);
369 }
370}
371
372void LightManager::SetDayNightCycle(const bool active) {
373 // 更新昼夜循环状态,参数 active 表示是否启用
374 _episode.Lock()->UpdateDayNightCycle(active);
375}
376
377} // namespace client
378} // namespace carla
FVehicleLightState LightState
Definition ActorData.h:131
std::vector< Light > GetTurnedOffLights(LightGroup type=LightGroup::None) const
std::vector< Light > GetTurnedOnLights(LightGroup type=LightGroup::None) const
std::vector< LightGroup > GetLightGroup(std::vector< Light > &lights) const
void SetIntensity(std::vector< Light > &lights, float intensity)
std::vector< bool > IsActive(std::vector< Light > &lights) const
std::vector< Color > GetColor(std::vector< Light > &lights) const
const LightState & RetrieveLightState(LightId id) const
void SetLightState(std::vector< Light > &lights, LightState state)
std::unordered_map< LightId, LightState > _lights_changes
void TurnOff(std::vector< Light > &lights)
void SetLightStateNoLock(LightId id, const LightState &new_state)
detail::WeakEpisodeProxy _episode
void SetColor(std::vector< Light > &lights, Color color)
void TurnOn(std::vector< Light > &lights)
std::vector< float > GetIntensity(std::vector< Light > &lights) const
void SetDayNightCycle(const bool active)
std::unordered_map< LightId, LightState > _lights_state
void SetLightGroup(std::vector< Light > &lights, LightGroup group)
void SetEpisode(detail::WeakEpisodeProxy episode)
void SetActive(std::vector< Light > &lights, std::vector< bool > &active)
std::unordered_map< LightId, Light > _lights
void UpdateServerLightsState(bool discard_client=false)
std::vector< LightState > GetLightState(std::vector< Light > &lights) const
std::vector< Light > GetAllLights(LightGroup type=LightGroup::None) const
EpisodeProxyImpl< EpisodeProxyPointerType::Weak > WeakEpisodeProxy
uint32_t LightId
定义灯光ID的类型,使用uint32_t表示。
CARLA模拟器的主命名空间。
Definition Carla.cpp:139
static void log_warning(Args &&... args)
Definition Logging.h:101
boost::shared_ptr< T > SharedPtr
使用这个SharedPtr(boost::shared_ptr)以保持与boost::python的兼容性, 但未来如果可能的话,我们希望能为std::shared_ptr制作一个Python适配器。
Definition Memory.h:19
包含CARLA客户端相关类和函数的命名空间。
表示车辆灯光状态的结构体。
float _intensity
灯光的强度,范围0.0到1.0。
bool _active
表示灯光是否激活的布尔值。
Color _color
灯光的颜色。
LightGroup _group
灯光所属的组。