CARLA
Loading...
Searching...
No Matches
LightManager.cpp
Go to the documentation of this file.
1// Copyright (c) 2026 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
16
18 // A destructor must not throw (that calls std::terminate), and the RPC below
19 // times out if the server is unreachable or stalled.
20#ifndef LIBCARLA_NO_EXCEPTIONS
21 try {
22#endif // LIBCARLA_NO_EXCEPTIONS
23 if(_episode.IsValid()) {
24 _episode.Lock()->RemoveOnTickEvent(_on_tick_register_id);
25 _episode.Lock()->RemoveLightUpdateChangeEvent(_on_light_update_register_id);
26 }
28#ifndef LIBCARLA_NO_EXCEPTIONS
29 } catch (const std::exception &e) {
30 log_error("exception in the light manager destructor:", e.what());
31 }
32#endif // LIBCARLA_NO_EXCEPTIONS
33}
34
36
37 _episode = episode;
38
39 _on_tick_register_id = _episode.Lock()->RegisterOnTickEvent(
40 [&](const WorldSnapshot&) {
42 });
43
44 _on_light_update_register_id = _episode.Lock()->RegisterLightUpdateChangeEvent(
45 [&](const WorldSnapshot& ) {
48 });
49
51}
52
53std::vector<Light> LightManager::GetAllLights(LightGroup type) const {
54 std::vector<Light> result;
55
56 for(auto lights_state : _lights_state) {
57 LightGroup group = lights_state.second._group;
58 if((type == LightGroup::None) || (group == type)) {
59 auto it_light = _lights.find(lights_state.first);
60 result.push_back(it_light->second);
61 }
62 }
63
64 return result;
65}
66
67void LightManager::TurnOn(std::vector<Light>& lights) {
68 for(Light& light : lights) {
69 SetActive(light._id, true);
70 }
71}
72
73void LightManager::TurnOff(std::vector<Light>& lights) {
74 for(Light& light : lights) {
75 SetActive(light._id, false);
76 }
77}
78
79void LightManager::SetActive(std::vector<Light>& lights, std::vector<bool>& active) {
80 size_t lights_to_update = (lights.size() < active.size()) ? lights.size() : active.size();
81 for(size_t i = 0; i < lights_to_update; i++) {
82 SetActive(lights[i]._id, active[i]);
83 }
84}
85
86std::vector<bool> LightManager::IsActive(std::vector<Light>& lights) const {
87 std::vector<bool> result;
88 for(Light& light : lights) {
89 result.push_back( IsActive(light._id) );
90 }
91 return result;
92}
93
94std::vector<Light> LightManager::GetTurnedOnLights(LightGroup type) const {
95 std::vector<Light> result;
96
97 for(auto lights_state : _lights_state) {
98 LightState& state = lights_state.second;
99 LightGroup group = state._group;
100 if( (type == LightGroup::None || group == type) && state._active ) {
101 auto it_light = _lights.find(lights_state.first);
102 result.push_back(it_light->second);
103 }
104 }
105
106 return result;
107}
108
109std::vector<Light> LightManager::GetTurnedOffLights(LightGroup type) const {
110 std::vector<Light> result;
111
112 for(auto lights_state : _lights_state) {
113 LightState& state = lights_state.second;
114 LightGroup group = state._group;
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
124void LightManager::SetColor(std::vector<Light>& lights, Color color) {
125 for(Light& light : lights) {
126 SetColor(light._id, color);
127 }
128}
129
130void LightManager::SetColor(std::vector<Light>& lights, std::vector<Color>& colors) {
131 size_t lights_to_update = (lights.size() < colors.size()) ? lights.size() : colors.size();
132 for(size_t i = 0; i < lights_to_update; i++) {
133 SetColor(lights[i]._id, colors[i]);
134 }
135}
136
137std::vector<Color> LightManager::GetColor(std::vector<Light>& lights) const {
138 std::vector<Color> result;
139 for(Light& light : lights) {
140 result.push_back( GetColor(light._id) );
141 }
142 return result;
143}
144
145void LightManager::SetIntensity(std::vector<Light>& lights, float intensity) {
146 for(Light& light : lights) {
147 SetIntensity(light._id, intensity);
148 }
149}
150
151void LightManager::SetIntensity(std::vector<Light>& lights, std::vector<float>& intensities) {
152 size_t lights_to_update = (lights.size() < intensities.size()) ? lights.size() : intensities.size();
153 for(size_t i = 0; i < lights_to_update; i++) {
154 SetIntensity(lights[i]._id, intensities[i]);
155 }
156}
157
158std::vector<float> LightManager::GetIntensity(std::vector<Light>& lights) const {
159 std::vector<float> result;
160 for(Light& light : lights) {
161 result.push_back( GetIntensity(light._id) );
162 }
163 return result;
164}
165
166void LightManager::SetLightGroup(std::vector<Light>& lights, LightGroup group) {
167 for(Light& light : lights) {
168 SetLightGroup(light._id, group);
169 }
170}
171
172void LightManager::SetLightGroup(std::vector<Light>& lights, std::vector<LightGroup>& groups) {
173 size_t lights_to_update = (lights.size() < groups.size()) ? lights.size() : groups.size();
174 for(size_t i = 0; i < lights_to_update; i++) {
175 SetLightGroup(lights[i]._id, groups[i]);
176 }
177}
178
179std::vector<LightGroup> LightManager::GetLightGroup(std::vector<Light>& lights) const {
180 std::vector<LightGroup> result;
181 for(Light& light : lights) {
182 result.push_back( GetLightGroup(light._id) );
183 }
184 return result;
185}
186
187void LightManager::SetLightState(std::vector<Light>& lights, LightState state) {
188 for(Light& light : lights) {
189 SetLightState(light._id, state);
190 }
191}
192
193void LightManager::SetLightState(std::vector<Light>& lights, std::vector<LightState>& states) {
194 size_t lights_to_update = (lights.size() < states.size()) ? lights.size() : states.size();
195 for(size_t i = 0; i < lights_to_update; i++) {
196 SetLightState(lights[i]._id, states[i]);
197 }
198}
199
200std::vector<LightState> LightManager::GetLightState(std::vector<Light>& lights) const {
201 std::vector<LightState> result;
202 for(Light& light : lights) {
203 result.push_back( RetrieveLightState(light._id) );
204 }
205 return result;
206}
207
211
215
219
223
225 return RetrieveLightState(id)._active;
226}
227
228void LightManager::SetActive(LightId id, bool active) {
229 std::scoped_lock<std::mutex> lock(_mutex);
230 LightState& state = const_cast<LightState&>(RetrieveLightState(id));
231 state._active = active;
232 _lights_changes[id] = state;
233 _dirty = true;
234}
235
237 std::scoped_lock<std::mutex> lock(_mutex);
238 LightState& state = const_cast<LightState&>(RetrieveLightState(id));
239 state._color = color;
240 _lights_changes[id] = state;
241 _dirty = true;
242}
243
245 std::scoped_lock<std::mutex> lock(_mutex);
246 LightState& state = const_cast<LightState&>(RetrieveLightState(id));
247 state._intensity = intensity;
248 _lights_changes[id] = state;
249 _dirty = true;
250}
251
253 std::scoped_lock<std::mutex> lock(_mutex);
254 LightState& state = const_cast<LightState&>(RetrieveLightState(id));
255 state = new_state;
256 _lights_changes[id] = state;
257 _dirty = true;
258}
259
261 LightState& state = const_cast<LightState&>(RetrieveLightState(id));
262 state = new_state;
263 _lights_changes[id] = state;
264}
265
267 std::scoped_lock<std::mutex> lock(_mutex);
268 LightState& state = const_cast<LightState&>(RetrieveLightState(id));
269 state._group = group;
270 _lights_changes[id] = state;
271 _dirty = true;
272}
273
275 auto it = _lights_state.find(id);
276 if(it == _lights_state.end()) {
277 carla::log_warning("Invalid light", id);
278 return _state;
279 }
280 return it->second;
281}
282
284 std::scoped_lock<std::mutex> lock(_mutex);
285 // Send blocking query
286 std::vector<rpc::LightState> lights_snapshot = _episode.Lock()->QueryLightsStateToServer();
287
288 // Update lights
289 SharedPtr<LightManager> lm = _episode.Lock()->GetLightManager();
290
291 // The snapshot is the whole set of lights the server has now: lights of
292 // World Partition cells that streamed out are gone from it, and their ids
293 // can come back for other lights. Merging into the cache kept every light
294 // ever seen, with its first location.
295 std::unordered_map<LightId, LightState> lights_state;
296 std::unordered_map<LightId, Light> lights;
297 for(const auto& it : lights_snapshot) {
298 lights_state[it._id] = LightState(
299 it._intensity,
300 Color(it._color.r, it._color.g, it._color.b),
301 static_cast<LightState::LightGroup>(it._group),
302 it._active
303 );
304 lights[it._id] = Light(lm, it._location, it._id);
305 }
306 _lights_state = std::move(lights_state);
307 _lights = std::move(lights);
308}
309
310void LightManager::UpdateServerLightsState(bool discard_client) {
311 std::scoped_lock<std::mutex> lock(_mutex);
312
313 if(_dirty) {
314 std::vector<rpc::LightState> message;
315 for(auto it : _lights_changes) {
316 auto it_light = _lights.find(it.first);
317 if(it_light != _lights.end()) {
318 rpc::LightState state(
319 it_light->second.GetLocation(),
320 it.second._intensity,
321 it.second._group,
322 rpc::Color(it.second._color.r, it.second._color.g, it.second._color.b),
323 it.second._active
324 );
325 state._id = it.first;
326 // Add to command
327 message.push_back(state);
328 }
329 }
330 _episode.Lock()->UpdateServerLightsState(message, discard_client);
331
332 _lights_changes.clear();
333 _dirty = false;
334 }
335}
336
338 std::scoped_lock<std::mutex> lock(_mutex);
339 for(const auto& it : _lights_changes) {
340 SetLightStateNoLock(it.first, it.second);
341 }
342}
343
344void LightManager::SetDayNightCycle(const bool active) {
345 _episode.Lock()->UpdateDayNightCycle(active);
346}
347
348} // namespace client
349} // namespace carla
float intensity
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
rpc::LightState::LightGroup LightGroup
Definition Light.cpp:16
This file contains definitions of common data structures used in traffic manager.
std::shared_ptr< T > SharedPtr
Definition Memory.h:15
static void log_error(Args &&... args)
Definition Logging.h:110
static void log_warning(Args &&... args)
Definition Logging.h:96