Make on_tick and wait_for_tick pass WorldSnapshot instead of Timestamps

This commit is contained in:
nsubiron 2019-06-17 18:33:40 +02:00 committed by Néstor Subirón
parent bbb95c3a51
commit e3e72206a2
17 changed files with 40 additions and 33 deletions

View File

@ -39,7 +39,7 @@
- `get_actors(actor_ids=None) -> carla.ActorList` - `get_actors(actor_ids=None) -> carla.ActorList`
- `spawn_actor(blueprint, transform, attach_to=None)` - `spawn_actor(blueprint, transform, attach_to=None)`
- `try_spawn_actor(blueprint, transform, attach_to=None, attachment_type=carla.AttachmentType.Rigid)` - `try_spawn_actor(blueprint, transform, attach_to=None, attachment_type=carla.AttachmentType.Rigid)`
- `wait_for_tick(seconds=1.0)` - `wait_for_tick(seconds=1.0) -> carla.WorldSnapshot`
- `on_tick(callback)` - `on_tick(callback)`
- `tick()` - `tick()`

View File

@ -63,7 +63,7 @@ namespace detail {
struct mapped_type { struct mapped_type {
bool should_wait; bool should_wait;
boost::variant<T, SharedException> value; boost::variant<SharedException, T> value;
}; };
std::map<const char *, mapped_type> _map; std::map<const char *, mapped_type> _map;
@ -80,6 +80,9 @@ namespace detail {
class SharedException : public std::exception { class SharedException : public std::exception {
public: public:
SharedException()
: _exception(std::make_shared<std::runtime_error>("uninitialized SharedException")) {}
SharedException(std::shared_ptr<std::exception> e) SharedException(std::shared_ptr<std::exception> e)
: _exception(std::move(e)) {} : _exception(std::move(e)) {}
@ -106,7 +109,7 @@ namespace detail {
if (!_cv.wait_for(lock, timeout.to_chrono(), [&]() { return !r.should_wait; })) { if (!_cv.wait_for(lock, timeout.to_chrono(), [&]() { return !r.should_wait; })) {
return {}; return {};
} }
if (r.value.which() == 1) { if (r.value.which() == 0) {
throw_exception(boost::get<SharedException>(r.value)); throw_exception(boost::get<SharedException>(r.value));
} }
return boost::get<T>(std::move(r.value)); return boost::get<T>(std::move(r.value));

View File

@ -37,10 +37,10 @@ namespace client {
log_debug(GetDisplayId(), ": subscribing to tick event"); log_debug(GetDisplayId(), ": subscribing to tick event");
GetEpisode().Lock()->RegisterOnTickEvent([ GetEpisode().Lock()->RegisterOnTickEvent([
cb=std::move(callback), cb=std::move(callback),
weak_self=WeakPtr<GnssSensor>(self)](const auto &timestamp) { weak_self=WeakPtr<GnssSensor>(self)](const auto &snapshot) {
auto self = weak_self.lock(); auto self = weak_self.lock();
if (self != nullptr) { if (self != nullptr) {
auto data = self->TickGnssSensor(timestamp); auto data = self->TickGnssSensor(snapshot.GetTimestamp());
if (data != nullptr) { if (data != nullptr) {
cb(std::move(data)); cb(std::move(data));
} }

View File

@ -62,10 +62,10 @@ namespace client {
log_debug(GetDisplayId(), ": subscribing to tick event"); log_debug(GetDisplayId(), ": subscribing to tick event");
GetEpisode().Lock()->RegisterOnTickEvent([ GetEpisode().Lock()->RegisterOnTickEvent([
cb=std::move(callback), cb=std::move(callback),
weak_self=WeakPtr<LaneInvasionSensor>(self)](const auto &timestamp) { weak_self=WeakPtr<LaneInvasionSensor>(self)](const auto &snapshot) {
auto self = weak_self.lock(); auto self = weak_self.lock();
if (self != nullptr) { if (self != nullptr) {
auto data = self->TickLaneInvasionSensor(timestamp); auto data = self->TickLaneInvasionSensor(snapshot.GetTimestamp());
if (data != nullptr) { if (data != nullptr) {
cb(std::move(data)); cb(std::move(data));
} }

View File

@ -89,11 +89,11 @@ namespace client {
} }
} }
Timestamp World::WaitForTick(time_duration timeout) const { WorldSnapshot World::WaitForTick(time_duration timeout) const {
return _episode.Lock()->WaitForTick(timeout); return _episode.Lock()->WaitForTick(timeout);
} }
void World::OnTick(std::function<void(Timestamp)> callback) { void World::OnTick(std::function<void(WorldSnapshot)> callback) {
return _episode.Lock()->RegisterOnTickEvent(std::move(callback)); return _episode.Lock()->RegisterOnTickEvent(std::move(callback));
} }

View File

@ -95,10 +95,10 @@ namespace client {
rpc::AttachmentType attachment_type = rpc::AttachmentType::Rigid) noexcept; rpc::AttachmentType attachment_type = rpc::AttachmentType::Rigid) noexcept;
/// Block calling thread until a world tick is received. /// Block calling thread until a world tick is received.
Timestamp WaitForTick(time_duration timeout) const; WorldSnapshot WaitForTick(time_duration timeout) const;
/// Register a @a callback to be called every time a world tick is received. /// Register a @a callback to be called every time a world tick is received.
void OnTick(std::function<void(Timestamp)> callback); void OnTick(std::function<void(WorldSnapshot)> callback);
/// Signal the simulator to continue to next tick (only has effect on /// Signal the simulator to continue to next tick (only has effect on
/// synchronous mode). /// synchronous mode).

View File

@ -18,6 +18,9 @@ namespace client {
class WorldSnapshot { class WorldSnapshot {
public: public:
WorldSnapshot(std::shared_ptr<const detail::EpisodeState> state)
: _state(std::move(state)) {}
/// Get the id of the episode associated with this world. /// Get the id of the episode associated with this world.
uint64_t GetId() const { uint64_t GetId() const {
return _state->GetEpisodeId(); return _state->GetEpisodeId();
@ -63,11 +66,6 @@ namespace client {
private: private:
friend class detail::Simulator;
explicit WorldSnapshot(std::shared_ptr<const detail::EpisodeState> &&state)
: _state(std::move(state)) {}
std::shared_ptr<const detail::EpisodeState> _state; std::shared_ptr<const detail::EpisodeState> _state;
}; };

View File

@ -57,7 +57,7 @@ namespace detail {
auto prev = self->GetState(); auto prev = self->GetState();
do { do {
if (prev->GetFrameCount() >= next->GetFrameCount()) { if (prev->GetFrameCount() >= next->GetFrameCount()) {
self->_on_tick_callbacks.Call(next->GetTimestamp()); self->_on_tick_callbacks.Call(next);
return; return;
} }
} while (!self->_state.compare_exchange(&prev, next)); } while (!self->_state.compare_exchange(&prev, next));
@ -67,8 +67,8 @@ namespace detail {
} }
// Notify waiting threads and do the callbacks. // Notify waiting threads and do the callbacks.
self->_timestamp.SetValue(next->GetTimestamp()); self->_snapshot.SetValue(next);
self->_on_tick_callbacks.Call(next->GetTimestamp()); self->_on_tick_callbacks.Call(next);
} }
}); });
} }

View File

@ -10,6 +10,7 @@
#include "carla/NonCopyable.h" #include "carla/NonCopyable.h"
#include "carla/RecurrentSharedFuture.h" #include "carla/RecurrentSharedFuture.h"
#include "carla/client/Timestamp.h" #include "carla/client/Timestamp.h"
#include "carla/client/WorldSnapshot.h"
#include "carla/client/detail/CachedActorList.h" #include "carla/client/detail/CachedActorList.h"
#include "carla/client/detail/CallbackList.h" #include "carla/client/detail/CallbackList.h"
#include "carla/client/detail/EpisodeState.h" #include "carla/client/detail/EpisodeState.h"
@ -57,11 +58,11 @@ namespace detail {
std::vector<rpc::Actor> GetActors(); std::vector<rpc::Actor> GetActors();
boost::optional<Timestamp> WaitForState(time_duration timeout) { boost::optional<WorldSnapshot> WaitForState(time_duration timeout) {
return _timestamp.WaitFor(timeout); return _snapshot.WaitFor(timeout);
} }
void RegisterOnTickEvent(std::function<void(Timestamp)> callback) { void RegisterOnTickEvent(std::function<void(WorldSnapshot)> callback) {
_on_tick_callbacks.RegisterCallback(std::move(callback)); _on_tick_callbacks.RegisterCallback(std::move(callback));
} }
@ -77,9 +78,9 @@ namespace detail {
CachedActorList _actors; CachedActorList _actors;
CallbackList<Timestamp> _on_tick_callbacks; CallbackList<WorldSnapshot> _on_tick_callbacks;
RecurrentSharedFuture<Timestamp> _timestamp; RecurrentSharedFuture<WorldSnapshot> _snapshot;
const streaming::Token _token; const streaming::Token _token;
}; };

View File

@ -95,7 +95,7 @@ namespace detail {
// -- Tick ------------------------------------------------------------------- // -- Tick -------------------------------------------------------------------
// =========================================================================== // ===========================================================================
Timestamp Simulator::WaitForTick(time_duration timeout) { WorldSnapshot Simulator::WaitForTick(time_duration timeout) {
DEBUG_ASSERT(_episode != nullptr); DEBUG_ASSERT(_episode != nullptr);
auto result = _episode->WaitForState(timeout); auto result = _episode->WaitForState(timeout);
if (!result.has_value()) { if (!result.has_value()) {

View File

@ -137,9 +137,9 @@ namespace detail {
// ========================================================================= // =========================================================================
/// @{ /// @{
Timestamp WaitForTick(time_duration timeout); WorldSnapshot WaitForTick(time_duration timeout);
void RegisterOnTickEvent(std::function<void(Timestamp)> callback) { void RegisterOnTickEvent(std::function<void(WorldSnapshot)> callback) {
DEBUG_ASSERT(_episode != nullptr); DEBUG_ASSERT(_episode != nullptr);
_episode->RegisterOnTickEvent(std::move(callback)); _episode->RegisterOnTickEvent(std::move(callback));
} }

View File

@ -43,6 +43,12 @@ void export_snapshot() {
class_<cc::WorldSnapshot>("WorldSnapshot", no_init) class_<cc::WorldSnapshot>("WorldSnapshot", no_init)
.add_property("id", &cc::WorldSnapshot::GetId) .add_property("id", &cc::WorldSnapshot::GetId)
.add_property("timestamp", CALL_RETURNING_COPY(cc::WorldSnapshot, GetTimestamp)) .add_property("timestamp", CALL_RETURNING_COPY(cc::WorldSnapshot, GetTimestamp))
/// Deprecated, use timestamp @{
.add_property("frame_count", +[](const cc::WorldSnapshot &self) { return self.GetTimestamp().frame_count; })
.add_property("elapsed_seconds", +[](const cc::WorldSnapshot &self) { return self.GetTimestamp().elapsed_seconds; })
.add_property("delta_seconds", +[](const cc::WorldSnapshot &self) { return self.GetTimestamp().delta_seconds; })
.add_property("platform_timestamp", +[](const cc::WorldSnapshot &self) { return self.GetTimestamp().platform_timestamp; })
/// @}
.def("has_actor", &cc::WorldSnapshot::Contains, (arg("actor_id"))) .def("has_actor", &cc::WorldSnapshot::Contains, (arg("actor_id")))
.def("find", CALL_RETURNING_OPTIONAL_1(cc::WorldSnapshot, Find, carla::ActorId), (arg("actor_id"))) .def("find", CALL_RETURNING_OPTIONAL_1(cc::WorldSnapshot, Find, carla::ActorId), (arg("actor_id")))
.def("__len__", &cc::WorldSnapshot::size) .def("__len__", &cc::WorldSnapshot::size)

View File

@ -753,8 +753,7 @@ def game_loop(args):
return return
# as soon as the server is ready continue! # as soon as the server is ready continue!
if not world.world.wait_for_tick(10.0): world.world.wait_for_tick(10.0)
continue
world.tick(clock) world.tick(clock)
world.render(display) world.render(display)

View File

@ -132,7 +132,7 @@ def main():
elapsed_time = 0.0 elapsed_time = 0.0
while True: while True:
timestamp = world.wait_for_tick(seconds=30.0) timestamp = world.wait_for_tick(seconds=30.0).timestamp
elapsed_time += timestamp.delta_seconds elapsed_time += timestamp.delta_seconds
if elapsed_time > update_freq: if elapsed_time > update_freq:
weather.tick(speed_factor * elapsed_time) weather.tick(speed_factor * elapsed_time)

View File

@ -118,7 +118,7 @@ def main():
clock.tick() clock.tick()
world.tick() world.tick()
ts = world.wait_for_tick() ts = world.wait_for_tick().timestamp
if frame is not None: if frame is not None:
if ts.frame_count != frame + 1: if ts.frame_count != frame + 1:

View File

@ -49,7 +49,7 @@ def main():
angle = 0 angle = 0
while angle < 356: while angle < 356:
timestamp = world.wait_for_tick() timestamp = world.wait_for_tick().timestamp
angle += timestamp.delta_seconds * 60.0 angle += timestamp.delta_seconds * 60.0
spectator.set_transform(get_transform(vehicle.get_location(), angle - 90)) spectator.set_transform(get_transform(vehicle.get_location(), angle - 90))

View File

@ -51,7 +51,7 @@ class TestSynchronousMode(SmokeTest):
for _ in range(0, 100): for _ in range(0, 100):
self.world.tick() self.world.tick()
ts = self.world.wait_for_tick() ts = self.world.wait_for_tick().timestamp
if frame is not None: if frame is not None:
self.assertEqual(ts.frame_count, frame + 1) self.assertEqual(ts.frame_count, frame + 1)