Fix #1272, allow changing the map from client-side

This commit is contained in:
nsubiron 2019-02-19 18:57:33 +01:00
parent 6a943333a1
commit 6bb2feb9b1
8 changed files with 60 additions and 0 deletions

View File

@ -12,6 +12,8 @@
- `get_client_version()`
- `get_server_version()`
- `get_world()`
- `reload_world()`
- `load_world(map_name)`
- `start_recorder(string filename)`
- `replay_file(string filename, float start, float duration, int camera_follow_id)`
- `show_recorder_file_info(string filename)`

View File

@ -43,6 +43,14 @@ namespace client {
return _simulator->GetServerVersion();
}
World ReloadWorld() {
return World{_simulator->ReloadEpisode()};
}
World LoadWorld(std::string map_name) {
return World{_simulator->LoadEpisode(std::move(map_name))};
}
/// Return an instance of the world currently active in the simulator.
World GetWorld() const {
return World{_simulator->GetCurrentEpisode()};

View File

@ -123,6 +123,11 @@ namespace detail {
return _pimpl->CallAndWait<std::string>("version");
}
void Client::LoadEpisode(std::string map_name) {
// Await response, we need to be sure in this one.
_pimpl->CallAndWait<void>("load_new_episode", std::move(map_name));
}
rpc::EpisodeInfo Client::GetEpisodeInfo() {
return _pimpl->CallAndWait<rpc::EpisodeInfo>("get_episode_info");
}

View File

@ -69,6 +69,8 @@ namespace detail {
std::string GetServerVersion();
void LoadEpisode(std::string map_name);
rpc::EpisodeInfo GetEpisodeInfo();
rpc::MapInfo GetMapInfo();

View File

@ -54,6 +54,24 @@ namespace detail {
_gc_policy(enable_garbage_collection ?
GarbageCollectionPolicy::Enabled : GarbageCollectionPolicy::Disabled) {}
// ===========================================================================
// -- Load a new episode -----------------------------------------------------
// ===========================================================================
EpisodeProxy Simulator::LoadEpisode(std::string map_name) {
const auto id = GetCurrentEpisode().GetId();
_client.LoadEpisode(std::move(map_name));
for (auto i = 0u; i < 10u; ++i) { // 10 attempts.
using namespace std::literals::chrono_literals;
WaitForTick(30s); /// @todo Do not throw on time-out.
auto episode = GetCurrentEpisode();
if (episode.GetId() != id) {
return episode;
}
}
throw_exception(std::runtime_error("failed to connect to newly created map"));
}
// ===========================================================================
// -- Access to current episode ----------------------------------------------
// ===========================================================================

View File

@ -53,12 +53,25 @@ namespace detail {
size_t worker_threads = 0u,
bool enable_garbage_collection = false);
/// @}
// =========================================================================
/// @name Load a new episode
// =========================================================================
/// @{
EpisodeProxy ReloadEpisode() {
return LoadEpisode("");
}
EpisodeProxy LoadEpisode(std::string map_name);
/// @}
// =========================================================================
/// @name Access to current episode
// =========================================================================
/// @{
/// @pre Cannot be called previous to GetCurrentEpisode.
auto GetCurrentEpisodeId() const {
DEBUG_ASSERT(_episode != nullptr);
return _episode->GetEpisode()->GetId();

View File

@ -22,6 +22,8 @@ void export_client() {
.def("get_client_version", &cc::Client::GetClientVersion)
.def("get_server_version", CONST_CALL_WITHOUT_GIL(cc::Client, GetServerVersion))
.def("get_world", &cc::Client::GetWorld)
.def("reload_world", CALL_WITHOUT_GIL(cc::Client, ReloadWorld))
.def("load_world", CALL_WITHOUT_GIL_1(cc::Client, LoadWorld, std::string), (arg("map_name")))
.def("start_recorder", CALL_WITHOUT_GIL_1(cc::Client, StartRecorder, std::string), (arg("name")))
.def("stop_recorder", &cc::Client::StopRecorder)
.def("show_recorder_file_info", CALL_WITHOUT_GIL_1(cc::Client, ShowRecorderFileInfo, std::string), (arg("name")))

View File

@ -123,6 +123,16 @@ void FTheNewCarlaServer::FPimpl::BindActions()
return R<void>::Success();
});
Server.BindSync("load_new_episode", [this](const std::string &map_name) -> R<void>
{
REQUIRE_CARLA_EPISODE();
if (!Episode->LoadNewEpisode(cr::ToFString(map_name)))
{
RESPOND_ERROR("map not found");
}
return R<void>::Success();
});
Server.BindSync("get_episode_info", [this]() -> R<cr::EpisodeInfo>
{
REQUIRE_CARLA_EPISODE();