CARLA
 
载入中...
搜索中...
未找到
LibCarla/source/carla/rss/RssSensor.cpp
浏览该文件的文档.
1// Copyright (c) 2019-2020 Intel Corporation
2//
3// This work is licensed under the terms of the MIT license.
4// For a copy, see <https://opensource.org/licenses/MIT>.
5
7
8#include <ad/map/access/Operation.hpp>
9#include <ad/rss/state/ProperResponse.hpp>
10#include <ad/rss/world/Velocity.hpp>
11#include <exception>
12#include <fstream>
13
14#include "carla/Logging.h"
15#include "carla/client/Map.h"
16#include "carla/client/Sensor.h"
19#include "carla/rss/RssCheck.h"
21
22namespace carla {
23namespace client {
24
26
27RssSensor::RssSensor(ActorInitializer init) : Sensor(std::move(init)), _on_tick_register_id(0u), _drop_route(false) {}
28
30 // ensure there is no processing anymore
31 if (IsListening()) {
32 Stop();
33 }
34}
35
37 if (IsListening()) {
39 ": registering of the actor constellation callback has to be done before start listening. Register has "
40 "no effect.");
41 return;
42 }
44}
45
47 if (IsListening()) {
48 log_error(GetDisplayId(), ": already listening");
49 return;
50 }
51
52 if (GetParent() == nullptr) {
53 throw_exception(std::runtime_error(GetDisplayId() + ": not attached to actor"));
54 return;
55 }
56
57 auto vehicle = boost::dynamic_pointer_cast<carla::client::Vehicle>(GetParent());
58 if (vehicle == nullptr) {
59 throw_exception(std::runtime_error(GetDisplayId() + ": parent is not a vehicle"));
60 return;
61 }
62
63 // get maximum steering angle
64 float max_steer_angle_deg = 0.f;
65 for (auto const &wheel : vehicle->GetPhysicsControl().GetWheels()) {
66 max_steer_angle_deg = std::max(max_steer_angle_deg, wheel.max_steer_angle);
67 }
68 auto max_steering_angle = max_steer_angle_deg * static_cast<float>(M_PI) / 180.0f;
69
70 auto map = GetWorld().GetMap();
71 DEBUG_ASSERT(map != nullptr);
72 std::string const open_drive_content = map->GetOpenDrive();
73
74 auto mapInitializationResult = ::ad::map::access::initFromOpenDriveContent(
75 open_drive_content, 0.2, ::ad::map::intersection::IntersectionType::TrafficLight,
76 ::ad::map::landmark::TrafficLightType::LEFT_STRAIGHT_RED_YELLOW_GREEN);
77
78 if (!mapInitializationResult) {
79 log_error(GetDisplayId(), ": Initialization of map failed");
80 return;
81 }
82
84
85 if (_rss_actor_constellation_callback == nullptr) {
86 _rss_check = std::make_shared<::carla::rss::RssCheck>(max_steering_angle);
87 } else {
89 std::make_shared<::carla::rss::RssCheck>(max_steering_angle, _rss_actor_constellation_callback, GetParent());
90 }
91
92 auto self = boost::static_pointer_cast<RssSensor>(shared_from_this());
93
95 log_debug(GetDisplayId(), ": subscribing to tick event");
96 _on_tick_register_id = GetEpisode().Lock()->RegisterOnTickEvent(
97 [ cb = std::move(callback), weak_self = WeakPtr<RssSensor>(self) ](const auto &snapshot) {
98 auto self = weak_self.lock();
99 if (self != nullptr) {
100 self->TickRssSensor(snapshot.GetTimestamp(), cb);
101 }
102 });
103}
104
106 if (!IsListening()) {
107 log_error(GetDisplayId(), ": not listening at all");
108 return;
109 }
110
111 log_debug(GetDisplayId(), ": unsubscribing from tick event");
112 GetEpisode().Lock()->RemoveOnTickEvent(_on_tick_register_id);
114
115 if ( bool(_rss_check) ) {
116 _rss_check->GetLogger()->info("RssSensor stopping");
117 }
118 // don't remove the braces since they protect the lock_guard
119 {
120 // ensure there is no processing anymore when deleting rss_check object
121 const std::lock_guard<std::mutex> lock(_processing_lock);
122
123 if ( bool(_rss_check) ) {
124 _rss_check->GetLogger()->info("RssSensor delete checker");
125 }
126 _rss_check.reset();
127 auto const map_initialization_counter_value = _global_map_initialization_counter_--;
128 if (map_initialization_counter_value == 0u) {
129 // last one stop listening is cleaning up the map
130 ::ad::map::access::cleanup();
131 }
132 }
133}
134
135void RssSensor::SetLogLevel(const uint8_t &log_level) {
136 if (!bool(_rss_check)) {
137 log_error(GetDisplayId(), ": not yet listening. SetLogLevel has no effect.");
138 return;
139 }
140
141 if (log_level < spdlog::level::n_levels) {
142 _rss_check->SetLogLevel(spdlog::level::level_enum(log_level));
143 }
144}
145
146void RssSensor::SetMapLogLevel(const uint8_t &map_log_level) {
147 if (!bool(_rss_check)) {
148 log_error(GetDisplayId(), ": not yet listening. SetMapLogLevel has no effect.");
149 return;
150 }
151
152 if (map_log_level < spdlog::level::n_levels) {
153 _rss_check->SetMapLogLevel(spdlog::level::level_enum(map_log_level));
154 }
155}
156
157const ::ad::rss::world::RssDynamics &RssSensor::GetEgoVehicleDynamics() const {
158 static auto default_vehicle_dynamics = rss::RssCheck::GetDefaultVehicleDynamics();
159 if (!bool(_rss_check)) {
160 log_error(GetDisplayId(), ": not yet listening. GetEgoVehicleDynamics has no effect.");
161 return default_vehicle_dynamics;
162 }
163
165 log_error(GetDisplayId(), ": Actor constellation callback registered. GetEgoVehicleDynamics has no effect.");
166 return default_vehicle_dynamics;
167 }
168
169 return _rss_check->GetDefaultActorConstellationCallbackEgoVehicleDynamics();
170}
171
172void RssSensor::SetEgoVehicleDynamics(const ::ad::rss::world::RssDynamics &ego_dynamics) {
173 if (!bool(_rss_check)) {
174 log_error(GetDisplayId(), ": not yet listening. SetEgoVehicleDynamics has no effect.");
175 return;
176 }
177
179 log_error(GetDisplayId(), ": Actor constellation callback registered. SetEgoVehicleDynamics has no effect.");
180 return;
181 }
182
183 _rss_check->SetDefaultActorConstellationCallbackEgoVehicleDynamics(ego_dynamics);
184}
185
186const ::ad::rss::world::RssDynamics &RssSensor::GetOtherVehicleDynamics() const {
187 static auto default_vehicle_dynamics = rss::RssCheck::GetDefaultVehicleDynamics();
188 if (!bool(_rss_check)) {
189 log_error(GetDisplayId(), ": not yet listening. GetOtherVehicleDynamics has no effect.");
190 return default_vehicle_dynamics;
191 }
192
194 log_error(GetDisplayId(), ": Actor constellation callback registered. GetOtherVehicleDynamics has no effect.");
195 return default_vehicle_dynamics;
196 }
197
198 return _rss_check->GetDefaultActorConstellationCallbackOtherVehicleDynamics();
199}
200
201void RssSensor::SetOtherVehicleDynamics(const ::ad::rss::world::RssDynamics &other_vehicle_dynamics) {
202 if (!bool(_rss_check)) {
203 log_error(GetDisplayId(), ": not yet listening. SetOtherVehicleDynamics has no effect.");
204 return;
205 }
206
208 log_error(GetDisplayId(), ": Actor constellation callback registered. SetOtherVehicleDynamics has no effect.");
209 return;
210 }
211
212 _rss_check->SetDefaultActorConstellationCallbackOtherVehicleDynamics(other_vehicle_dynamics);
213}
214
215const ::ad::rss::world::RssDynamics &RssSensor::GetPedestrianDynamics() const {
216 static auto default_pedestrian_dynamics = rss::RssCheck::GetDefaultPedestrianDynamics();
217 if (!bool(_rss_check)) {
218 log_error(GetDisplayId(), ": not yet listening. GetPedestrianDynamics has no effect.");
219 return default_pedestrian_dynamics;
220 }
221
223 log_error(GetDisplayId(), ": Actor constellation callback registered. GetPedestrianDynamics has no effect.");
224 return default_pedestrian_dynamics;
225 }
226
227 return _rss_check->GetDefaultActorConstellationCallbackPedestrianDynamics();
228}
229
230void RssSensor::SetPedestrianDynamics(const ::ad::rss::world::RssDynamics &pedestrian_dynamics) {
231 if (!bool(_rss_check)) {
232 log_error(GetDisplayId(), ": not yet listening. SetPedestrianDynamics has no effect.");
233 return;
234 }
235
237 log_error(GetDisplayId(), ": Actor constellation callback registered. SetPedestrianDynamics has no effect.");
238 return;
239 }
240
241 _rss_check->SetDefaultActorConstellationCallbackPedestrianDynamics(pedestrian_dynamics);
242}
243
244const ::carla::rss::RoadBoundariesMode &RssSensor::GetRoadBoundariesMode() const {
245 if (!bool(_rss_check)) {
246 log_error(GetDisplayId(), ": not yet listening. GetRoadBoundariesMode has no effect.");
247 static auto default_road_boundaries_mode = rss::RssCheck::GetDefaultRoadBoundariesMode();
248 return default_road_boundaries_mode;
249 }
250
251 return _rss_check->GetRoadBoundariesMode();
252}
253
254void RssSensor::SetRoadBoundariesMode(const ::carla::rss::RoadBoundariesMode &road_boundaries_mode) {
255 if (!bool(_rss_check)) {
256 log_error(GetDisplayId(), ": not yet listening. SetRoadBoundariesMode has no effect.");
257 return;
258 }
259
260 _rss_check->SetRoadBoundariesMode(road_boundaries_mode);
261}
262
263void RssSensor::AppendRoutingTarget(const ::carla::geom::Transform &routing_target) {
264 if (!bool(_rss_check)) {
265 log_error(GetDisplayId(), ": not yet listening. AppendRoutingTarget has no effect.");
266 return;
267 }
268
269 _rss_check->AppendRoutingTarget(routing_target);
270}
271
272const std::vector<::carla::geom::Transform> RssSensor::GetRoutingTargets() const {
273 if (!bool(_rss_check)) {
274 log_error(GetDisplayId(), ": not yet listening. GetRoutingTargets has no effect.");
275 return std::vector<::carla::geom::Transform>();
276 }
277
278 return _rss_check->GetRoutingTargets();
279}
280
282 if (!bool(_rss_check)) {
283 log_error(GetDisplayId(), ": not yet listening. ResetRoutingTargets has no effect.");
284 return;
285 }
286
287 _rss_check->ResetRoutingTargets();
288}
289
291 // don't execute this immediately as it might break calculations completely
292 // postpone to next sensor tick
293 _drop_route = true;
294}
295
297 if (_processing_lock.try_lock()) {
298 if (!bool(_rss_check)){
299 _processing_lock.unlock();
300 return;
301 }
302 if ((timestamp.frame < _last_processed_frame) && ((_last_processed_frame - timestamp.frame) < 0xffffffffu)) {
303 _processing_lock.unlock();
304 _rss_check->GetLogger()->warn("RssSensor[{}] outdated tick dropped, LastProcessed={}", timestamp.frame, _last_processed_frame);
305 return;
306 }
307 _last_processed_frame = timestamp.frame;
309
310 auto const settings = GetWorld().GetSettings();
311 if ( settings.synchronous_mode ) {
312 _rss_check->GetLogger()->info("RssSensor[{}] sync-tick", timestamp.frame);
313 TickRssSensorThreadLocked(timestamp, actors, callback);
314 }
315 else {
316 // store the future to prevent the destructor of the future from blocked waiting
317 _rss_check->GetLogger()->info("RssSensor[{}] async-tick", timestamp.frame);
318 _tick_future = std::async(&RssSensor::TickRssSensorThreadLocked, this, timestamp, actors, callback);
319 }
320 } else {
321 if (bool(_rss_check)){
322 _rss_check->GetLogger()->info("RssSensor[{}] tick dropped", timestamp.frame);
323 }
324 }
325}
326
329 try {
330 double const time_since_epoch_check_start_ms =
331 std::chrono::duration<double, std::milli>(std::chrono::system_clock::now().time_since_epoch()).count();
332
333 if (_drop_route) {
334 _drop_route = false;
335 _rss_check->DropRoute();
336 }
337
338 // check all object<->ego pairs with RSS and calculate proper response
339 ::ad::rss::state::ProperResponse response;
340 ::ad::rss::state::RssStateSnapshot rss_state_snapshot;
341 ::ad::rss::situation::SituationSnapshot situation_snapshot;
342 ::ad::rss::world::WorldModel world_model;
343 carla::rss::EgoDynamicsOnRoute ego_dynamics_on_route;
344 auto const result = _rss_check->CheckObjects(timestamp, actors, GetParent(), response, rss_state_snapshot,
345 situation_snapshot, world_model, ego_dynamics_on_route);
346
347 double const time_since_epoch_check_end_ms =
348 std::chrono::duration<double, std::milli>(std::chrono::system_clock::now().time_since_epoch()).count();
349 auto const delta_time_ms = time_since_epoch_check_end_ms - time_since_epoch_check_start_ms;
350 _rss_check->GetLogger()->debug("RssSensor[{}] response: S:{}->E:{} DeltaT:{}", timestamp.frame,
351 time_since_epoch_check_start_ms, time_since_epoch_check_end_ms,
352 delta_time_ms);
353 _rss_check_timings.push_back(delta_time_ms);
354 while (_rss_check_timings.size() > 10u) {
355 _rss_check_timings.pop_front();
356 }
357 double agv_time=0.;
358 for (auto run_time: _rss_check_timings) {
359 agv_time += run_time;
360 }
361 agv_time /= _rss_check_timings.size();
362 _rss_check->GetLogger()->info("RssSensor[{}] runtime {} avg {}", timestamp.frame, delta_time_ms, agv_time);
363 _processing_lock.unlock();
364
365 callback(MakeShared<sensor::data::RssResponse>(timestamp.frame, timestamp.elapsed_seconds, GetTransform(), result,
366 response, rss_state_snapshot, situation_snapshot, world_model,
367 ego_dynamics_on_route));
368 } catch (const std::exception &e) {
369 _rss_check->GetLogger()->error("RssSensor[{}] tick exception", timestamp.frame);
370 _processing_lock.unlock();
371 } catch (...) {
372 _rss_check->GetLogger()->error("RssSensor[{}] tick exception", timestamp.frame);
373 _processing_lock.unlock();
374 }
375}
376
377} // namespace client
378} // namespace carla
#define DEBUG_ASSERT(predicate)
Definition Debug.h:66
Used to initialize Actor classes.
geom::Transform GetTransform() const
Return the current transform of the actor.
Definition Actor.cpp:19
std::size_t _last_processed_frame
last processed frame
std::future< void > _tick_future
the future for the async ticking thread
void ResetRoutingTargets()
resets the current routing target (
std::size_t _on_tick_register_id
the id got when registering for the on tick event
bool IsListening() const override
Return whether this Sensor instance is currently listening to the associated sensor in the simulator.
const ::ad::rss::world::RssDynamics & GetOtherVehicleDynamics() const
void SetLogLevel(const uint8_t &log_level)
sets the current log level
void SetEgoVehicleDynamics(const ::ad::rss::world::RssDynamics &ego_dynamics)
sets the ego vehicle dynamics to be used by the ego vehicle (
std::shared_ptr<::carla::rss::RssCheck > _rss_check
static std::atomic_uint _global_map_initialization_counter_
void SetPedestrianDynamics(const ::ad::rss::world::RssDynamics &pedestrian_dynamics)
sets the ego vehicle dynamics to be used by pedestrians (
void RegisterActorConstellationCallback(ActorConstellationCallbackFunctionType callback)
Register a callback to be executed for each actor within each measurement to be processed to decide o...
std::function<::carla::rss::ActorConstellationResult(carla::SharedPtr<::carla::rss::ActorConstellationData >)> ActorConstellationCallbackFunctionType
void Stop() override
Stop listening for new measurements.
const ::ad::rss::world::RssDynamics & GetPedestrianDynamics() const
void TickRssSensor(const client::Timestamp &timestamp, CallbackFunctionType callback)
the acutal sensor tick callback function
void SetOtherVehicleDynamics(const ::ad::rss::world::RssDynamics &other_vehicle_dynamics)
sets the ego vehicle dynamics to be used by other vehicles (
void SetMapLogLevel(const uint8_t &map_log_level)
sets the current map log level
std::list< double > _rss_check_timings
some debug timings
const ::ad::rss::world::RssDynamics & GetEgoVehicleDynamics() const
RssSensor(ActorInitializer init)
constructor
void AppendRoutingTarget(const ::carla::geom::Transform &routing_target)
appends a routing target to the current routing target list (
std::mutex _processing_lock
the mutex to protect the actual RSS processing and in case it takes too long to process ever frame
void SetRoadBoundariesMode(const ::carla::rss::RoadBoundariesMode &road_boundaries_mode)
sets the current mode for respecting the road boundaries (
ActorConstellationCallbackFunctionType _rss_actor_constellation_callback
const ::carla::rss::RoadBoundariesMode & GetRoadBoundariesMode() const
const std::vector<::carla::geom::Transform > GetRoutingTargets() const
void Listen(CallbackFunctionType callback) override
Register a callback to be executed each time a new measurement is received.
bool _drop_route
reqired to store DropRoute() requests until next sensor tick
void TickRssSensorThreadLocked(const client::Timestamp &timestamp, SharedPtr< carla::client::ActorList > actors, CallbackFunctionType callback)
std::function< void(SharedPtr< sensor::SensorData >)> CallbackFunctionType
std::size_t frame
Number of frames elapsed since the simulator was launched.
Definition Timestamp.h:30
double elapsed_seconds
Simulated seconds elapsed since the beginning of the current episode.
Definition Timestamp.h:33
SharedPtr< ActorList > GetActors() const
Return a list with all the actors currently present in the world.
Definition World.cpp:115
SharedPtr< Map > GetMap() const
Return the map that describes this world.
Definition World.cpp:24
rpc::EpisodeSettings GetSettings() const
Definition World.cpp:52
SharedPtr< Actor > GetParent() const
const std::string & GetDisplayId() const
SharedPtrType Lock() const
Same as TryLock but never return nullptr.
::ad::rss::world::RssDynamics GetDefaultVehicleDynamics()
Definition RssCheck.cpp:88
static RoadBoundariesMode GetDefaultRoadBoundariesMode()
Definition RssCheck.h:217
::ad::rss::world::RssDynamics GetDefaultPedestrianDynamics()
Definition RssCheck.cpp:107
This file contains definitions of common data structures used in traffic manager.
Definition Carla.cpp:133
void throw_exception(const std::exception &e)
Definition Carla.cpp:135
boost::weak_ptr< T > WeakPtr
Definition Memory.h:23
static void log_error(Args &&... args)
Definition Logging.h:110
boost::shared_ptr< T > SharedPtr
Use this SharedPtr (boost::shared_ptr) to keep compatibility with boost::python, but it would be nice...
Definition Memory.h:20
static void log_debug(Args &&... args)
Definition Logging.h:68
struct defining the ego vehicles current dynamics in respect to the current route
Definition RssCheck.h:40