Make Simulator class, leave Client to pure networking methods only
This commit is contained in:
parent
38b9822860
commit
c7de4c0be7
|
@ -7,7 +7,7 @@
|
|||
#include "carla/client/Actor.h"
|
||||
|
||||
#include "carla/Logging.h"
|
||||
#include "carla/client/detail/Client.h"
|
||||
#include "carla/client/detail/Simulator.h"
|
||||
|
||||
namespace carla {
|
||||
namespace client {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "carla/PythonUtil.h"
|
||||
#include "carla/client/World.h"
|
||||
#include "carla/client/detail/Client.h"
|
||||
#include "carla/client/detail/Simulator.h"
|
||||
|
||||
namespace carla {
|
||||
namespace client {
|
||||
|
@ -28,36 +28,36 @@ namespace client {
|
|||
size_t worker_threads = 0u);
|
||||
|
||||
void SetTimeout(time_duration timeout) {
|
||||
_client_state->SetTimeout(timeout);
|
||||
_simulator->SetNetworkingTimeout(timeout);
|
||||
}
|
||||
|
||||
std::string GetClientVersion() const {
|
||||
return _client_state->GetClientVersion();
|
||||
return _simulator->GetClientVersion();
|
||||
}
|
||||
|
||||
std::string GetServerVersion() const {
|
||||
return _client_state->GetServerVersion();
|
||||
return _simulator->GetServerVersion();
|
||||
}
|
||||
|
||||
bool Ping() const {
|
||||
return _client_state->Ping();
|
||||
return _simulator->Ping();
|
||||
}
|
||||
|
||||
World GetWorld() const {
|
||||
return _client_state->GetCurrentEpisode();
|
||||
return World{_simulator->GetCurrentEpisode()};
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SharedPtr<detail::Client> _client_state;
|
||||
SharedPtr<detail::Simulator> _simulator;
|
||||
};
|
||||
|
||||
inline Client::Client(
|
||||
const std::string &host,
|
||||
uint16_t port,
|
||||
size_t worker_threads)
|
||||
: _client_state(
|
||||
new detail::Client(host, port, worker_threads),
|
||||
: _simulator(
|
||||
new detail::Simulator(host, port, worker_threads),
|
||||
PythonUtil::ReleaseGILDeleter()) {}
|
||||
|
||||
} // namespace client
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "carla/client/Sensor.h"
|
||||
|
||||
#include "carla/Logging.h"
|
||||
#include "carla/client/detail/Client.h"
|
||||
#include "carla/client/detail/Simulator.h"
|
||||
|
||||
namespace carla {
|
||||
namespace client {
|
||||
|
@ -32,9 +32,7 @@ namespace client {
|
|||
GetDisplayId());
|
||||
return;
|
||||
}
|
||||
GetEpisode()->SubscribeToStream(
|
||||
GetActorDescription().GetStreamToken(),
|
||||
std::move(callback));
|
||||
GetEpisode()->SubscribeToSensor(*this, std::move(callback));
|
||||
_is_listening = true;
|
||||
}
|
||||
|
||||
|
@ -45,8 +43,7 @@ namespace client {
|
|||
GetDisplayId());
|
||||
return;
|
||||
}
|
||||
GetEpisode()->UnSubscribeFromStream(
|
||||
GetActorDescription().GetStreamToken());
|
||||
GetEpisode()->UnSubscribeFromSensor(*this);
|
||||
_is_listening = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#include "carla/client/Vehicle.h"
|
||||
#include "carla/client/detail/Client.h"
|
||||
|
||||
#include "carla/client/detail/Simulator.h"
|
||||
|
||||
namespace carla {
|
||||
namespace client {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "carla/Logging.h"
|
||||
#include "carla/client/Actor.h"
|
||||
#include "carla/client/ActorBlueprint.h"
|
||||
#include "carla/client/detail/Client.h"
|
||||
#include "carla/client/detail/Simulator.h"
|
||||
|
||||
#include <exception>
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "carla/Memory.h"
|
||||
#include "carla/client/detail/Episode.h"
|
||||
#include "carla/client/detail/EpisodeProxy.h"
|
||||
#include "carla/geom/Transform.h"
|
||||
#include "carla/rpc/WeatherParameters.h"
|
||||
|
||||
|
@ -21,7 +21,7 @@ namespace client {
|
|||
class World {
|
||||
public:
|
||||
|
||||
World(detail::Episode episode) : _episode(std::move(episode)) {}
|
||||
explicit World(detail::EpisodeProxy episode) : _episode(std::move(episode)) {}
|
||||
|
||||
World(const World &) = default;
|
||||
World(World &&) = default;
|
||||
|
@ -49,7 +49,7 @@ namespace client {
|
|||
|
||||
private:
|
||||
|
||||
detail::Episode _episode;
|
||||
detail::EpisodeProxy _episode;
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
|
|
|
@ -55,11 +55,6 @@ namespace detail {
|
|||
|
||||
template <typename ActorT>
|
||||
static auto MakeActorImpl(ActorInitializer init, GarbageCollectionPolicy gc) {
|
||||
log_debug(
|
||||
init.GetDisplayId(),
|
||||
"created",
|
||||
gc == GarbageCollectionPolicy::Enabled ? "with" : "without",
|
||||
"garbage collection");
|
||||
if (gc == GarbageCollectionPolicy::Enabled) {
|
||||
return SharedPtr<ActorT>{new ActorT(std::move(init)), GarbageCollector()};
|
||||
}
|
||||
|
@ -68,17 +63,15 @@ namespace detail {
|
|||
}
|
||||
|
||||
SharedPtr<Actor> ActorFactory::MakeActor(
|
||||
Episode episode,
|
||||
EpisodeProxy episode,
|
||||
rpc::Actor description,
|
||||
GarbageCollectionPolicy gc) {
|
||||
const auto gcw = episode->GetGarbageCollectionPolicy();
|
||||
const auto gca = (gc == GarbageCollectionPolicy::Inherit ? gcw : gc);
|
||||
if (description.HasAStream()) {
|
||||
return MakeActorImpl<Sensor>(ActorInitializer{description, episode}, gca);
|
||||
return MakeActorImpl<Sensor>(ActorInitializer{description, episode}, gc);
|
||||
} else if (StringUtil::StartsWith(description.description.id, "vehicle.")) {
|
||||
return MakeActorImpl<Vehicle>(ActorInitializer{description, episode}, gca);
|
||||
return MakeActorImpl<Vehicle>(ActorInitializer{description, episode}, gc);
|
||||
}
|
||||
return MakeActorImpl<Actor>(ActorInitializer{description, episode}, gca);
|
||||
return MakeActorImpl<Actor>(ActorInitializer{description, episode}, gc);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "carla/Memory.h"
|
||||
#include "carla/client/GarbageCollectionPolicy.h"
|
||||
#include "carla/client/detail/Episode.h"
|
||||
#include "carla/client/detail/EpisodeProxy.h"
|
||||
#include "carla/rpc/Actor.h"
|
||||
|
||||
namespace carla {
|
||||
|
@ -22,9 +22,9 @@ namespace detail {
|
|||
public:
|
||||
|
||||
static SharedPtr<Actor> MakeActor(
|
||||
Episode episode,
|
||||
EpisodeProxy episode,
|
||||
rpc::Actor actor_description,
|
||||
GarbageCollectionPolicy gc = GarbageCollectionPolicy::Inherit);
|
||||
GarbageCollectionPolicy gc);
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "carla/NonCopyable.h"
|
||||
#include "carla/client/World.h"
|
||||
#include "carla/client/detail/EpisodeProxy.h"
|
||||
#include "carla/rpc/Actor.h"
|
||||
|
||||
namespace carla {
|
||||
|
@ -16,6 +17,7 @@ namespace detail {
|
|||
|
||||
class ActorFactory;
|
||||
|
||||
/// Internal state of an Actor.
|
||||
class ActorState : private MovableNonCopyable {
|
||||
public:
|
||||
|
||||
|
@ -30,7 +32,7 @@ namespace detail {
|
|||
std::string GetDisplayId() const;
|
||||
|
||||
World GetWorld() const {
|
||||
return _episode;
|
||||
return World{_episode};
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -39,29 +41,31 @@ namespace detail {
|
|||
return _description;
|
||||
}
|
||||
|
||||
Episode &GetEpisode() {
|
||||
EpisodeProxy &GetEpisode() {
|
||||
return _episode;
|
||||
}
|
||||
|
||||
const Episode &GetEpisode() const {
|
||||
const EpisodeProxy &GetEpisode() const {
|
||||
return _episode;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
friend class detail::Client;
|
||||
friend class Simulator;
|
||||
|
||||
ActorState(rpc::Actor description, Episode episode)
|
||||
ActorState(rpc::Actor description, EpisodeProxy episode)
|
||||
: _description(std::move(description)),
|
||||
_episode(std::move(episode)) {}
|
||||
|
||||
rpc::Actor _description;
|
||||
|
||||
Episode _episode;
|
||||
EpisodeProxy _episode;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Used to initialize Actor classes. Only the ActorFactory can create this
|
||||
/// object, thus only the ActorFactory can create actors.
|
||||
class ActorInitializer : public detail::ActorState {
|
||||
public:
|
||||
ActorInitializer(ActorInitializer &&) = default;
|
||||
|
|
|
@ -7,13 +7,9 @@
|
|||
#include "carla/client/detail/Client.h"
|
||||
|
||||
#include "carla/Version.h"
|
||||
#include "carla/client/Actor.h"
|
||||
#include "carla/client/BlueprintLibrary.h"
|
||||
#include "carla/client/Vehicle.h"
|
||||
#include "carla/client/World.h"
|
||||
#include "carla/client/detail/ActorFactory.h"
|
||||
#include "carla/client/detail/Episode.h"
|
||||
#include "carla/rpc/ActorDescription.h"
|
||||
#include "carla/rpc/Client.h"
|
||||
#include "carla/rpc/VehicleControl.h"
|
||||
#include "carla/sensor/Deserializer.h"
|
||||
#include "carla/streaming/Client.h"
|
||||
|
||||
|
@ -60,12 +56,8 @@ namespace detail {
|
|||
Client::Client(
|
||||
const std::string &host,
|
||||
const uint16_t port,
|
||||
const size_t worker_threads,
|
||||
const bool enable_garbage_collection)
|
||||
: LIBCARLA_INITIALIZE_LIFETIME_PROFILER("carla::client::detail::Client"),
|
||||
_pimpl(std::make_unique<Pimpl>(host, port, worker_threads)),
|
||||
_gc_policy(enable_garbage_collection ?
|
||||
GarbageCollectionPolicy::Enabled : GarbageCollectionPolicy::Disabled) {}
|
||||
const size_t worker_threads)
|
||||
: _pimpl(std::make_unique<Pimpl>(host, port, worker_threads)) {}
|
||||
|
||||
Client::~Client() = default;
|
||||
|
||||
|
@ -73,12 +65,6 @@ namespace detail {
|
|||
_pimpl->rpc_client.set_timeout(timeout.milliseconds());
|
||||
}
|
||||
|
||||
// Keep this function in the cpp, to avoid recompiling everything on each
|
||||
// commit.
|
||||
std::string Client::GetClientVersion() {
|
||||
return ::carla::version();
|
||||
}
|
||||
|
||||
std::string Client::GetServerVersion() {
|
||||
return _pimpl->CallAndWait<std::string>("version");
|
||||
}
|
||||
|
@ -87,60 +73,63 @@ namespace detail {
|
|||
return _pimpl->CallAndWait<bool>("ping");
|
||||
}
|
||||
|
||||
SharedPtr<BlueprintLibrary> Client::GetBlueprintLibrary() {
|
||||
using return_type = std::vector<carla::rpc::ActorDefinition>;
|
||||
auto result = _pimpl->CallAndWait<return_type>("get_actor_definitions");
|
||||
return MakeShared<BlueprintLibrary>(result);
|
||||
std::vector<rpc::ActorDefinition> Client::GetActorDefinitions() {
|
||||
return _pimpl->CallAndWait<std::vector<rpc::ActorDefinition>>("get_actor_definitions");
|
||||
}
|
||||
|
||||
SharedPtr<Actor> Client::GetSpectator() {
|
||||
auto spectator = _pimpl->CallAndWait<carla::rpc::Actor>("get_spectator");
|
||||
return ActorFactory::MakeActor(
|
||||
GetCurrentEpisode(),
|
||||
spectator,
|
||||
GarbageCollectionPolicy::Disabled);
|
||||
rpc::Actor Client::GetSpectator() {
|
||||
return _pimpl->CallAndWait<carla::rpc::Actor>("get_spectator");
|
||||
}
|
||||
|
||||
rpc::WeatherParameters Client::GetWeatherParameters() {
|
||||
return _pimpl->CallAndWait<rpc::WeatherParameters>("get_weather");
|
||||
return _pimpl->CallAndWait<rpc::WeatherParameters>("get_weather_parameters");
|
||||
}
|
||||
|
||||
void Client::SetWeatherParameters(const rpc::WeatherParameters &weather) {
|
||||
_pimpl->AsyncCall("set_weather", weather);
|
||||
_pimpl->AsyncCall("set_weather_parameters", weather);
|
||||
}
|
||||
|
||||
SharedPtr<Actor> Client::SpawnActor(
|
||||
const ActorBlueprint &blueprint,
|
||||
rpc::Actor Client::SpawnActor(
|
||||
const rpc::ActorDescription &description,
|
||||
const geom::Transform &transform) {
|
||||
return _pimpl->CallAndWait<rpc::Actor>("spawn_actor", description, transform);
|
||||
}
|
||||
|
||||
rpc::Actor Client::SpawnActorWithParent(
|
||||
const rpc::ActorDescription &description,
|
||||
const geom::Transform &transform,
|
||||
Actor *parent,
|
||||
GarbageCollectionPolicy gc) {
|
||||
rpc::Actor actor;
|
||||
if (parent != nullptr) {
|
||||
actor = _pimpl->CallAndWait<rpc::Actor>("spawn_actor_with_parent",
|
||||
transform,
|
||||
blueprint.MakeActorDescription(),
|
||||
parent->Serialize());
|
||||
} else {
|
||||
actor = _pimpl->CallAndWait<rpc::Actor>("spawn_actor",
|
||||
transform,
|
||||
blueprint.MakeActorDescription());
|
||||
}
|
||||
return ActorFactory::MakeActor(GetCurrentEpisode(), actor, gc);
|
||||
const rpc::Actor &parent) {
|
||||
return _pimpl->CallAndWait<rpc::Actor>("spawn_actor_with_parent",
|
||||
description,
|
||||
transform,
|
||||
parent);
|
||||
}
|
||||
|
||||
bool Client::DestroyActor(Actor &actor) {
|
||||
auto result = _pimpl->CallAndWait<bool>("destroy_actor", actor.Serialize());
|
||||
// Remove it's persistent state so it cannot access the client anymore.
|
||||
actor.GetEpisode().ClearState();
|
||||
log_debug(actor.GetDisplayId(), "destroyed.");
|
||||
return result;
|
||||
bool Client::DestroyActor(const rpc::Actor &actor) {
|
||||
return _pimpl->CallAndWait<bool>("destroy_actor", actor);
|
||||
}
|
||||
|
||||
void Client::SetActorLocation(const rpc::Actor &actor, const geom::Location &location) {
|
||||
_pimpl->AsyncCall("set_actor_location", actor, location);
|
||||
}
|
||||
|
||||
void Client::SetActorTransform(const rpc::Actor &actor, const geom::Transform &transform) {
|
||||
_pimpl->AsyncCall("set_actor_transform", actor, transform);
|
||||
}
|
||||
|
||||
void Client::SetActorAutopilot(const rpc::Actor &vehicle, const bool enabled) {
|
||||
_pimpl->AsyncCall("set_actor_autopilot", vehicle, enabled);
|
||||
}
|
||||
|
||||
void Client::ApplyControlToActor(const rpc::Actor &vehicle, const rpc::VehicleControl &control) {
|
||||
_pimpl->AsyncCall("apply_control_to_actor", vehicle, control);
|
||||
}
|
||||
|
||||
void Client::SubscribeToStream(
|
||||
const streaming::Token &token,
|
||||
std::function<void(SharedPtr<sensor::SensorData>)> callback) {
|
||||
_pimpl->streaming_client.Subscribe(token, [callback](auto buffer) {
|
||||
callback(sensor::Deserializer::Deserialize(std::move(buffer)));
|
||||
_pimpl->streaming_client.Subscribe(token, [cb=std::move(callback)](auto buffer) {
|
||||
cb(sensor::Deserializer::Deserialize(std::move(buffer)));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -148,34 +137,6 @@ namespace detail {
|
|||
_pimpl->streaming_client.UnSubscribe(token);
|
||||
}
|
||||
|
||||
geom::Location Client::GetActorLocation(const Actor &actor) {
|
||||
return _pimpl->CallAndWait<geom::Location>("get_actor_location", actor.Serialize());
|
||||
}
|
||||
|
||||
geom::Transform Client::GetActorTransform(const Actor &actor) {
|
||||
return _pimpl->CallAndWait<geom::Transform>("get_actor_transform", actor.Serialize());
|
||||
}
|
||||
|
||||
void Client::SetActorLocation(Actor &actor, const geom::Location &location) {
|
||||
_pimpl->AsyncCall("set_actor_location", actor.Serialize(), location);
|
||||
}
|
||||
|
||||
void Client::SetActorTransform(Actor &actor, const geom::Transform &transform) {
|
||||
_pimpl->AsyncCall("set_actor_transform", actor.Serialize(), transform);
|
||||
}
|
||||
|
||||
void Client::SetVehicleAutopilot(
|
||||
Vehicle &vehicle,
|
||||
const bool enabled) {
|
||||
_pimpl->AsyncCall("set_actor_autopilot", vehicle.Serialize(), enabled);
|
||||
}
|
||||
|
||||
void Client::ApplyControlToVehicle(
|
||||
Vehicle &vehicle,
|
||||
const rpc::VehicleControl &control) {
|
||||
_pimpl->AsyncCall("apply_control_to_actor", vehicle.Serialize(), control);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace client
|
||||
} // namespace carla
|
||||
|
|
|
@ -9,26 +9,22 @@
|
|||
#include "carla/Memory.h"
|
||||
#include "carla/NonCopyable.h"
|
||||
#include "carla/Time.h"
|
||||
#include "carla/client/GarbageCollectionPolicy.h"
|
||||
#include "carla/client/detail/Episode.h"
|
||||
#include "carla/geom/Transform.h"
|
||||
#include "carla/profiler/LifetimeProfiled.h"
|
||||
#include "carla/rpc/Actor.h"
|
||||
#include "carla/rpc/ActorDefinition.h"
|
||||
#include "carla/rpc/WeatherParameters.h"
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Forward declarations.
|
||||
namespace carla {
|
||||
namespace client {
|
||||
class Actor;
|
||||
class ActorBlueprint;
|
||||
class BlueprintLibrary;
|
||||
class Vehicle;
|
||||
class Episode;
|
||||
namespace rpc {
|
||||
class ActorDescription;
|
||||
class VehicleControl;
|
||||
}
|
||||
namespace rpc { class VehicleControl; }
|
||||
namespace sensor { class SensorData; }
|
||||
namespace streaming { class Token; }
|
||||
}
|
||||
|
@ -37,44 +33,60 @@ namespace carla {
|
|||
namespace client {
|
||||
namespace detail {
|
||||
|
||||
/// Provides communication with the rpc and streaming servers of a CARLA
|
||||
/// simulator.
|
||||
///
|
||||
/// @todo Make sure this class is really thread-safe.
|
||||
class Client
|
||||
: public EnableSharedFromThis<Client>,
|
||||
private profiler::LifetimeProfiled,
|
||||
private NonCopyable {
|
||||
class Client : private NonCopyable {
|
||||
public:
|
||||
|
||||
explicit Client(
|
||||
const std::string &host,
|
||||
uint16_t port,
|
||||
size_t worker_threads = 0u,
|
||||
bool enable_garbage_collection = false);
|
||||
size_t worker_threads = 0u);
|
||||
|
||||
~Client();
|
||||
|
||||
void SetTimeout(time_duration timeout);
|
||||
|
||||
std::string GetClientVersion();
|
||||
|
||||
std::string GetServerVersion();
|
||||
|
||||
bool Ping();
|
||||
|
||||
SharedPtr<BlueprintLibrary> GetBlueprintLibrary();
|
||||
std::vector<rpc::ActorDefinition> GetActorDefinitions();
|
||||
|
||||
SharedPtr<Actor> GetSpectator();
|
||||
rpc::Actor GetSpectator();
|
||||
|
||||
rpc::WeatherParameters GetWeatherParameters();
|
||||
|
||||
void SetWeatherParameters(const rpc::WeatherParameters &weather);
|
||||
|
||||
SharedPtr<Actor> SpawnActor(
|
||||
const ActorBlueprint &blueprint,
|
||||
const geom::Transform &transform,
|
||||
Actor *parent,
|
||||
GarbageCollectionPolicy gc = GarbageCollectionPolicy::Inherit);
|
||||
rpc::Actor SpawnActor(
|
||||
const rpc::ActorDescription &description,
|
||||
const geom::Transform &transform);
|
||||
|
||||
bool DestroyActor(Actor &actor);
|
||||
rpc::Actor SpawnActorWithParent(
|
||||
const rpc::ActorDescription &description,
|
||||
const geom::Transform &transform,
|
||||
const rpc::Actor &parent);
|
||||
|
||||
bool DestroyActor(const rpc::Actor &actor);
|
||||
|
||||
void SetActorLocation(
|
||||
const rpc::Actor &actor,
|
||||
const geom::Location &location);
|
||||
|
||||
void SetActorTransform(
|
||||
const rpc::Actor &actor,
|
||||
const geom::Transform &transform);
|
||||
|
||||
void SetActorAutopilot(
|
||||
const rpc::Actor &vehicle,
|
||||
bool enabled);
|
||||
|
||||
void ApplyControlToActor(
|
||||
const rpc::Actor &vehicle,
|
||||
const rpc::VehicleControl &control);
|
||||
|
||||
void SubscribeToStream(
|
||||
const streaming::Token &token,
|
||||
|
@ -82,40 +94,10 @@ namespace detail {
|
|||
|
||||
void UnSubscribeFromStream(const streaming::Token &token);
|
||||
|
||||
geom::Location GetActorLocation(const Actor &actor);
|
||||
|
||||
geom::Transform GetActorTransform(const Actor &actor);
|
||||
|
||||
void SetActorLocation(Actor &actor, const geom::Location &location);
|
||||
|
||||
void SetActorTransform(Actor &actor, const geom::Transform &transform);
|
||||
|
||||
void SetVehicleAutopilot(Vehicle &vehicle, bool enabled = true);
|
||||
|
||||
void ApplyControlToVehicle(Vehicle &vehicle, const rpc::VehicleControl &control);
|
||||
|
||||
GarbageCollectionPolicy GetGarbageCollectionPolicy() const {
|
||||
return _gc_policy;
|
||||
}
|
||||
|
||||
size_t GetCurrentEpisodeId() const {
|
||||
return _episode_id;
|
||||
}
|
||||
|
||||
Episode GetCurrentEpisode() {
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
class Pimpl;
|
||||
const std::unique_ptr<Pimpl> _pimpl;
|
||||
|
||||
const GarbageCollectionPolicy _gc_policy;
|
||||
|
||||
// At this point the id won't change because we cannot yet restart the
|
||||
// episode from the client.
|
||||
const size_t _episode_id = 0u;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "carla/Debug.h"
|
||||
#include "carla/Memory.h"
|
||||
#include "carla/client/detail/PersistentState.h"
|
||||
|
||||
namespace carla {
|
||||
namespace client {
|
||||
namespace detail {
|
||||
|
||||
class EpisodeImpl {
|
||||
public:
|
||||
|
||||
PersistentState &operator*() const {
|
||||
return GetPersistentStateWithChecks();
|
||||
}
|
||||
|
||||
PersistentState *operator->() const {
|
||||
return &GetPersistentStateWithChecks();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
EpisodeImpl(SharedPtr<PersistentState> state);
|
||||
|
||||
void ClearState();
|
||||
|
||||
private:
|
||||
|
||||
PersistentState &GetPersistentStateWithChecks() const;
|
||||
|
||||
SharedPtr<PersistentState> _state;
|
||||
|
||||
size_t _episode_id;
|
||||
};
|
||||
|
||||
class Episode : private EpisodeImpl {
|
||||
public:
|
||||
|
||||
using EpisodeImpl::operator*;
|
||||
using EpisodeImpl::operator->;
|
||||
|
||||
private:
|
||||
|
||||
friend PersistentState;
|
||||
|
||||
using EpisodeImpl::EpisodeImpl;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace client
|
||||
} // namespace carla
|
|
@ -4,9 +4,9 @@
|
|||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#include "carla/client/detail/Episode.h"
|
||||
#include "carla/client/detail/EpisodeProxy.h"
|
||||
|
||||
#include "carla/client/detail/Client.h"
|
||||
#include "carla/client/detail/Simulator.h"
|
||||
|
||||
#include <boost/atomic.hpp>
|
||||
|
||||
|
@ -16,27 +16,27 @@ namespace carla {
|
|||
namespace client {
|
||||
namespace detail {
|
||||
|
||||
EpisodeImpl::EpisodeImpl(SharedPtr<PersistentState> state)
|
||||
: _state(std::move(state)),
|
||||
_episode_id(_state->GetCurrentEpisodeId()) {}
|
||||
EpisodeProxyImpl::EpisodeProxyImpl(SharedPtr<Simulator> simulator)
|
||||
: _simulator(std::move(simulator)),
|
||||
_episode_id(_simulator->GetCurrentEpisodeId()) {}
|
||||
|
||||
void EpisodeImpl::ClearState() {
|
||||
boost::atomic_store_explicit(&_state, {nullptr}, boost::memory_order_relaxed);
|
||||
void EpisodeProxyImpl::ClearState() {
|
||||
boost::atomic_store_explicit(&_simulator, {nullptr}, boost::memory_order_relaxed);
|
||||
}
|
||||
|
||||
PersistentState &EpisodeImpl::GetPersistentStateWithChecks() const {
|
||||
auto state = boost::atomic_load_explicit(&_state, boost::memory_order_relaxed);
|
||||
Simulator &EpisodeProxyImpl::GetSimulatorWithChecks() const {
|
||||
auto state = boost::atomic_load_explicit(&_simulator, boost::memory_order_relaxed);
|
||||
if (state == nullptr) {
|
||||
throw std::runtime_error(
|
||||
"trying to operate on a destroyed actor; an actor's function "
|
||||
"was called, but the actor is already destroyed.");
|
||||
}
|
||||
if (_episode_id != _state->GetCurrentEpisodeId()) {
|
||||
if (_episode_id != _simulator->GetCurrentEpisodeId()) {
|
||||
throw std::runtime_error(
|
||||
"trying to access an expired episode; a new episode was started "
|
||||
"in the simulation but an object tried accessing the old one.");
|
||||
}
|
||||
return *_state;
|
||||
return *_simulator;
|
||||
}
|
||||
|
||||
} // namespace detail
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "carla/Memory.h"
|
||||
|
||||
namespace carla {
|
||||
namespace client {
|
||||
namespace detail {
|
||||
|
||||
class Simulator;
|
||||
|
||||
/// Private implementation of a EpisodeProxy.
|
||||
class EpisodeProxyImpl {
|
||||
public:
|
||||
|
||||
Simulator &operator*() const {
|
||||
return GetSimulatorWithChecks();
|
||||
}
|
||||
|
||||
Simulator *operator->() const {
|
||||
return &GetSimulatorWithChecks();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
EpisodeProxyImpl(SharedPtr<Simulator> simulator);
|
||||
|
||||
void ClearState();
|
||||
|
||||
private:
|
||||
|
||||
Simulator &GetSimulatorWithChecks() const;
|
||||
|
||||
SharedPtr<Simulator> _simulator;
|
||||
|
||||
size_t _episode_id;
|
||||
};
|
||||
|
||||
/// Provides access to the Simulator during a given episode. After the episode
|
||||
/// is ended any access to the simulator throws an std::runtime_error.
|
||||
class EpisodeProxy : private EpisodeProxyImpl {
|
||||
public:
|
||||
|
||||
using EpisodeProxyImpl::operator*;
|
||||
using EpisodeProxyImpl::operator->;
|
||||
|
||||
private:
|
||||
|
||||
friend class Simulator;
|
||||
|
||||
using EpisodeProxyImpl::EpisodeProxyImpl;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace client
|
||||
} // namespace carla
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "carla/NonCopyable.h"
|
||||
#include "carla/rpc/EpisodeInfo.h"
|
||||
|
||||
namespace carla {
|
||||
namespace client {
|
||||
namespace detail {
|
||||
|
||||
/// Represents an episode running on the Simulator.
|
||||
class EpisodeState : private MovableNonCopyable {
|
||||
public:
|
||||
|
||||
EpisodeState() = default; /// @todo
|
||||
|
||||
EpisodeState(rpc::EpisodeInfo description)
|
||||
: _description(std::move(description)) {}
|
||||
|
||||
auto GetId() const {
|
||||
return _description.id;
|
||||
}
|
||||
|
||||
const std::string &GetMapName() const {
|
||||
return _description.map_name;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
rpc::EpisodeInfo _description;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace client
|
||||
} // namespace carla
|
|
@ -1,23 +0,0 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
// #include "carla/client/detail/Client.h"
|
||||
|
||||
namespace carla {
|
||||
namespace client {
|
||||
namespace detail {
|
||||
|
||||
class Client;
|
||||
|
||||
/// At this point the client is the only persistent state we have, but
|
||||
/// conceptually is nice to make the distinction.
|
||||
using PersistentState = Client;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace client
|
||||
} // namespace carla
|
|
@ -0,0 +1,120 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#include "carla/client/detail/Simulator.h"
|
||||
|
||||
#include "carla/Logging.h"
|
||||
#include "carla/client/BlueprintLibrary.h"
|
||||
#include "carla/client/Sensor.h"
|
||||
#include "carla/client/detail/ActorFactory.h"
|
||||
|
||||
#include <exception>
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
namespace carla {
|
||||
namespace client {
|
||||
namespace detail {
|
||||
|
||||
// ===========================================================================
|
||||
// -- Constructor ------------------------------------------------------------
|
||||
// ===========================================================================
|
||||
|
||||
Simulator::Simulator(
|
||||
const std::string &host,
|
||||
const uint16_t port,
|
||||
const size_t worker_threads,
|
||||
const bool enable_garbage_collection)
|
||||
: LIBCARLA_INITIALIZE_LIFETIME_PROFILER("SimulatorClient("s + host + ":" + std::to_string(port) + ")"),
|
||||
_client(host, port, worker_threads),
|
||||
_episode(), /// @todo
|
||||
_gc_policy(enable_garbage_collection ?
|
||||
GarbageCollectionPolicy::Enabled : GarbageCollectionPolicy::Disabled) {}
|
||||
|
||||
// ===========================================================================
|
||||
// -- Access to global objects in the episode --------------------------------
|
||||
// ===========================================================================
|
||||
|
||||
SharedPtr<BlueprintLibrary> Simulator::GetBlueprintLibrary() {
|
||||
return MakeShared<BlueprintLibrary>(_client.GetActorDefinitions());
|
||||
}
|
||||
|
||||
SharedPtr<Actor> Simulator::GetSpectator() {
|
||||
return ActorFactory::MakeActor(
|
||||
GetCurrentEpisode(),
|
||||
_client.GetSpectator(),
|
||||
GarbageCollectionPolicy::Disabled);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// -- General operations with actors -----------------------------------------
|
||||
// ===========================================================================
|
||||
|
||||
SharedPtr<Actor> Simulator::SpawnActor(
|
||||
const ActorBlueprint &blueprint,
|
||||
const geom::Transform &transform,
|
||||
Actor *parent,
|
||||
GarbageCollectionPolicy gc) {
|
||||
rpc::Actor actor;
|
||||
if (parent != nullptr) {
|
||||
actor = _client.SpawnActorWithParent(
|
||||
blueprint.MakeActorDescription(),
|
||||
transform,
|
||||
parent->Serialize());
|
||||
} else {
|
||||
actor = _client.SpawnActor(
|
||||
blueprint.MakeActorDescription(),
|
||||
transform);
|
||||
}
|
||||
const auto gca = (gc == GarbageCollectionPolicy::Inherit ? _gc_policy : gc);
|
||||
auto result = ActorFactory::MakeActor(GetCurrentEpisode(), actor, gca);
|
||||
log_debug(
|
||||
result->GetDisplayId(),
|
||||
"created",
|
||||
gca == GarbageCollectionPolicy::Enabled ? "with" : "without",
|
||||
"garbage collection");
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Simulator::DestroyActor(Actor &actor) {
|
||||
auto success = _client.DestroyActor(actor.Serialize());
|
||||
if (success) {
|
||||
// Remove it's persistent state so it cannot access the client anymore.
|
||||
actor.GetEpisode().ClearState();
|
||||
log_debug(actor.GetDisplayId(), "destroyed.");
|
||||
} else {
|
||||
log_debug("failed to destroy", actor.GetDisplayId());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
geom::Location Simulator::GetActorLocation(const Actor &) {
|
||||
throw std::runtime_error("GetActorLocation() not implemented!");
|
||||
}
|
||||
|
||||
geom::Transform Simulator::GetActorTransform(const Actor &) {
|
||||
throw std::runtime_error("GetActorTransform() not implemented!");
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// -- Operations with sensors ------------------------------------------------
|
||||
// ===========================================================================
|
||||
|
||||
void Simulator::SubscribeToSensor(
|
||||
const Sensor &sensor,
|
||||
std::function<void(SharedPtr<sensor::SensorData>)> callback) {
|
||||
_client.SubscribeToStream(
|
||||
sensor.GetActorDescription().GetStreamToken(),
|
||||
std::move(callback));
|
||||
}
|
||||
|
||||
void Simulator::UnSubscribeFromSensor(const Sensor &sensor) {
|
||||
_client.UnSubscribeFromStream(sensor.GetActorDescription().GetStreamToken());
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace client
|
||||
} // namespace carla
|
|
@ -0,0 +1,179 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "carla/Memory.h"
|
||||
#include "carla/NonCopyable.h"
|
||||
#include "carla/Version.h"
|
||||
#include "carla/client/Actor.h"
|
||||
#include "carla/client/GarbageCollectionPolicy.h"
|
||||
#include "carla/client/Vehicle.h"
|
||||
#include "carla/client/detail/Client.h"
|
||||
#include "carla/client/detail/EpisodeProxy.h"
|
||||
#include "carla/client/detail/EpisodeState.h"
|
||||
#include "carla/profiler/LifetimeProfiled.h"
|
||||
|
||||
namespace carla {
|
||||
namespace client {
|
||||
|
||||
class ActorBlueprint;
|
||||
class BlueprintLibrary;
|
||||
class Episode;
|
||||
class Sensor;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/// Connects and controls a CARLA Simulator.
|
||||
///
|
||||
/// @todo Make sure this class is really thread-safe.
|
||||
class Simulator
|
||||
: public EnableSharedFromThis<Simulator>,
|
||||
private profiler::LifetimeProfiled,
|
||||
private NonCopyable {
|
||||
public:
|
||||
|
||||
// =========================================================================
|
||||
/// @name Constructor
|
||||
// =========================================================================
|
||||
/// @{
|
||||
|
||||
explicit Simulator(
|
||||
const std::string &host,
|
||||
uint16_t port,
|
||||
size_t worker_threads = 0u,
|
||||
bool enable_garbage_collection = false);
|
||||
|
||||
/// @}
|
||||
// =========================================================================
|
||||
/// @name Access to current episode
|
||||
// =========================================================================
|
||||
/// @{
|
||||
|
||||
auto GetCurrentEpisodeId() const {
|
||||
return _episode.GetId();
|
||||
}
|
||||
|
||||
EpisodeProxy GetCurrentEpisode() {
|
||||
return EpisodeProxy{shared_from_this()};
|
||||
}
|
||||
|
||||
/// @}
|
||||
// =========================================================================
|
||||
/// @name Garbage collection policy
|
||||
// =========================================================================
|
||||
/// @{
|
||||
|
||||
GarbageCollectionPolicy GetGarbageCollectionPolicy() const {
|
||||
return _gc_policy;
|
||||
}
|
||||
|
||||
/// @}
|
||||
// =========================================================================
|
||||
/// @name Pure networking operations
|
||||
// =========================================================================
|
||||
/// @{
|
||||
|
||||
void SetNetworkingTimeout(time_duration timeout) {
|
||||
_client.SetTimeout(timeout);
|
||||
}
|
||||
|
||||
std::string GetClientVersion() {
|
||||
return ::carla::version();
|
||||
}
|
||||
|
||||
std::string GetServerVersion() {
|
||||
return _client.GetServerVersion();
|
||||
}
|
||||
|
||||
bool Ping() {
|
||||
return _client.Ping();
|
||||
}
|
||||
|
||||
/// @}
|
||||
// =========================================================================
|
||||
/// @name Access to global objects in the episode
|
||||
// =========================================================================
|
||||
/// @{
|
||||
|
||||
SharedPtr<BlueprintLibrary> GetBlueprintLibrary();
|
||||
|
||||
SharedPtr<Actor> GetSpectator();
|
||||
|
||||
rpc::WeatherParameters GetWeatherParameters() {
|
||||
return _client.GetWeatherParameters();
|
||||
}
|
||||
|
||||
void SetWeatherParameters(const rpc::WeatherParameters &weather) {
|
||||
_client.SetWeatherParameters(weather);
|
||||
}
|
||||
|
||||
/// @}
|
||||
// =========================================================================
|
||||
/// @name General operations with actors
|
||||
// =========================================================================
|
||||
/// @{
|
||||
|
||||
SharedPtr<Actor> SpawnActor(
|
||||
const ActorBlueprint &blueprint,
|
||||
const geom::Transform &transform,
|
||||
Actor *parent = nullptr,
|
||||
GarbageCollectionPolicy gc = GarbageCollectionPolicy::Inherit);
|
||||
|
||||
bool DestroyActor(Actor &actor);
|
||||
|
||||
geom::Location GetActorLocation(const Actor &actor);
|
||||
|
||||
geom::Transform GetActorTransform(const Actor &actor);
|
||||
|
||||
void SetActorLocation(Actor &actor, const geom::Location &location) {
|
||||
_client.SetActorLocation(actor.Serialize(), location);
|
||||
}
|
||||
|
||||
void SetActorTransform(Actor &actor, const geom::Transform &transform) {
|
||||
_client.SetActorTransform(actor.Serialize(), transform);
|
||||
}
|
||||
|
||||
/// @}
|
||||
// =========================================================================
|
||||
/// @name Operations with vehicles
|
||||
// =========================================================================
|
||||
/// @{
|
||||
|
||||
void SetVehicleAutopilot(Vehicle &vehicle, bool enabled = true) {
|
||||
_client.SetActorAutopilot(vehicle.Serialize(), enabled);
|
||||
}
|
||||
|
||||
void ApplyControlToVehicle(Vehicle &vehicle, const rpc::VehicleControl &control) {
|
||||
_client.ApplyControlToActor(vehicle.Serialize(), control);
|
||||
}
|
||||
|
||||
/// @}
|
||||
// =========================================================================
|
||||
/// @name Operations with sensors
|
||||
// =========================================================================
|
||||
/// @{
|
||||
|
||||
void SubscribeToSensor(
|
||||
const Sensor &sensor,
|
||||
std::function<void(SharedPtr<sensor::SensorData>)> callback);
|
||||
|
||||
void UnSubscribeFromSensor(const Sensor &sensor);
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
|
||||
Client _client;
|
||||
|
||||
EpisodeState _episode;
|
||||
|
||||
GarbageCollectionPolicy _gc_policy;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace client
|
||||
} // namespace carla
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "carla/MsgPack.h"
|
||||
#include "carla/streaming/Token.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace carla {
|
||||
namespace rpc {
|
||||
|
||||
class EpisodeInfo {
|
||||
public:
|
||||
|
||||
using id_type = uint32_t;
|
||||
|
||||
id_type id;
|
||||
|
||||
std::string map_name;
|
||||
|
||||
streaming::Token token;
|
||||
|
||||
MSGPACK_DEFINE_ARRAY(id, map_name, token);
|
||||
};
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace carla
|
|
@ -149,7 +149,7 @@ void FTheNewCarlaServer::FPimpl::BindActions()
|
|||
return ActorView;
|
||||
});
|
||||
|
||||
Server.BindSync("get_weather", [this]() -> cr::WeatherParameters {
|
||||
Server.BindSync("get_weather_parameters", [this]() -> cr::WeatherParameters {
|
||||
RequireEpisode();
|
||||
auto *Weather = Episode->GetWeather();
|
||||
if (Weather == nullptr) {
|
||||
|
@ -158,7 +158,7 @@ void FTheNewCarlaServer::FPimpl::BindActions()
|
|||
return Weather->GetCurrentWeather();
|
||||
});
|
||||
|
||||
Server.BindSync("set_weather", [this](const cr::WeatherParameters &weather) {
|
||||
Server.BindSync("set_weather_parameters", [this](const cr::WeatherParameters &weather) {
|
||||
RequireEpisode();
|
||||
auto *Weather = Episode->GetWeather();
|
||||
if (Weather == nullptr) {
|
||||
|
@ -168,15 +168,15 @@ void FTheNewCarlaServer::FPimpl::BindActions()
|
|||
});
|
||||
|
||||
Server.BindSync("spawn_actor", [this](
|
||||
const cr::Transform &Transform,
|
||||
cr::ActorDescription Description) -> cr::Actor {
|
||||
cr::ActorDescription Description,
|
||||
const cr::Transform &Transform) -> cr::Actor {
|
||||
RequireEpisode();
|
||||
return SerializeActor(SpawnActor(Transform, Description));
|
||||
});
|
||||
|
||||
Server.BindSync("spawn_actor_with_parent", [this](
|
||||
const cr::Transform &Transform,
|
||||
cr::ActorDescription Description,
|
||||
const cr::Transform &Transform,
|
||||
cr::Actor Parent) -> cr::Actor {
|
||||
RequireEpisode();
|
||||
auto ActorView = SpawnActor(Transform, Description);
|
||||
|
|
Loading…
Reference in New Issue