Adding load control on sublevels (#3515)
* Added MapLayer enum * Added Load/Unload layer functions * Added calls to register and tag objects on map change * Added missing file * Updated MapLayer to support more layers * Added calls to PythonAPI * Added default value * Moved CurrentMapLayer to GI * Updated manual_control with maplayer handling * Updated help * Updated Changelog * Fixed a missing `;` * Fixed LoadWorld() API so it works with old code * Added missing include for shipping builds * Fixed base enum type of MapLayer * Removed int number from layer output * Renamed variables * MapLayer converted to int32 and added generic enumToString function * MapLayer back to uint16 Co-authored-by: Marc Garcia Puig <marcgpuig@gmail.com>
This commit is contained in:
parent
7a14a53107
commit
8f1b401e49
|
@ -1,9 +1,9 @@
|
|||
## Latest
|
||||
* Updated the bounding box calculation of two wheeled vehicles to include the character inside the bounding box
|
||||
* Added `load_map_layer` and `unload_map_layer` to control map layers on new maps that support subleveling
|
||||
* Added `get_environment_objects`call to get all the placed objects in the level
|
||||
* Added `enable_environment_objects`call to enable/disable objects of the level
|
||||
* Added fully deterministic option for Traffic Manager, sorting vehicles by ID and avoiding race conditions.
|
||||
* Fixed RSSSensor python3 build and import of open drive maps by updating to ad-rss v4.2.0 and ad-map-access v2.3.0. Python import of dependent 'ad' python modules reflects now the namespaces of the C++ interface and follow doxygen documentation.
|
||||
* Added fully deterministic option for Traffic Manager, sorting vehicles by ID and avoiding race conditions
|
||||
* Fixed RSSSensor python3 build and import of open drive maps by updating to ad-rss v4.2.0 and ad-map-access v2.3.0. Python import of dependent 'ad' python modules reflects now the namespaces of the C++ interface and follow doxygen documentation
|
||||
* Fixed sensor transformations and sensor data transformations mismatch in IMU and camera-based sensors
|
||||
* Fixed random dead-lock on synchronous mode at high frame rate
|
||||
* API extensions:
|
||||
|
|
|
@ -58,8 +58,10 @@ namespace client {
|
|||
return World{_simulator->ReloadEpisode()};
|
||||
}
|
||||
|
||||
World LoadWorld(std::string map_name) const {
|
||||
return World{_simulator->LoadEpisode(std::move(map_name))};
|
||||
World LoadWorld(
|
||||
std::string map_name,
|
||||
rpc::MapLayer map_layers = rpc::MapLayer::All) const {
|
||||
return World{_simulator->LoadEpisode(std::move(map_name), map_layers)};
|
||||
}
|
||||
|
||||
World GenerateOpenDriveWorld(
|
||||
|
|
|
@ -22,6 +22,14 @@ namespace client {
|
|||
return _episode.Lock()->GetCurrentMap();
|
||||
}
|
||||
|
||||
void World::LoadLevelLayer(rpc::MapLayer map_layers) const {
|
||||
_episode.Lock()->LoadLevelLayer(map_layers);
|
||||
}
|
||||
|
||||
void World::UnloadLevelLayer(rpc::MapLayer map_layers) const {
|
||||
_episode.Lock()->UnloadLevelLayer(map_layers);
|
||||
}
|
||||
|
||||
SharedPtr<BlueprintLibrary> World::GetBlueprintLibrary() const {
|
||||
return _episode.Lock()->GetBlueprintLibrary();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "carla/rpc/EpisodeSettings.h"
|
||||
#include "carla/rpc/EnvironmentObject.h"
|
||||
#include "carla/rpc/LabelledPoint.h"
|
||||
#include "carla/rpc/MapLayer.h"
|
||||
#include "carla/rpc/VehiclePhysicsControl.h"
|
||||
#include "carla/rpc/WeatherParameters.h"
|
||||
#include "carla/rpc/VehicleLightStateList.h"
|
||||
|
@ -58,6 +59,10 @@ namespace client {
|
|||
/// Return the map that describes this world.
|
||||
SharedPtr<Map> GetMap() const;
|
||||
|
||||
void LoadLevelLayer(rpc::MapLayer map_layers) const;
|
||||
|
||||
void UnloadLevelLayer(rpc::MapLayer map_layers) const;
|
||||
|
||||
/// Return the list of blueprints available in this world. This blueprints
|
||||
/// can be used to spawning actor into the world.
|
||||
SharedPtr<BlueprintLibrary> GetBlueprintLibrary() const;
|
||||
|
|
|
@ -140,9 +140,19 @@ namespace detail {
|
|||
return _pimpl->CallAndWait<std::string>("version");
|
||||
}
|
||||
|
||||
void Client::LoadEpisode(std::string map_name) {
|
||||
void Client::LoadEpisode(std::string map_name, rpc::MapLayer map_layer) {
|
||||
// Await response, we need to be sure in this one.
|
||||
_pimpl->CallAndWait<void>("load_new_episode", std::move(map_name));
|
||||
_pimpl->CallAndWait<void>("load_new_episode", std::move(map_name), map_layer);
|
||||
}
|
||||
|
||||
void Client::LoadLevelLayer(rpc::MapLayer map_layer) const {
|
||||
// Await response, we need to be sure in this one.
|
||||
_pimpl->CallAndWait<void>("load_map_layer", map_layer);
|
||||
}
|
||||
|
||||
void Client::UnloadLevelLayer(rpc::MapLayer map_layer) const {
|
||||
// Await response, we need to be sure in this one.
|
||||
_pimpl->CallAndWait<void>("unload_map_layer", map_layer);
|
||||
}
|
||||
|
||||
void Client::CopyOpenDriveToServer(std::string opendrive, const rpc::OpendriveGenerationParameters & params) {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "carla/rpc/LabelledPoint.h"
|
||||
#include "carla/rpc/LightState.h"
|
||||
#include "carla/rpc/MapInfo.h"
|
||||
#include "carla/rpc/MapLayer.h"
|
||||
#include "carla/rpc/EnvironmentObject.h"
|
||||
#include "carla/rpc/TrafficLightState.h"
|
||||
#include "carla/rpc/VehiclePhysicsControl.h"
|
||||
|
@ -90,7 +91,11 @@ namespace detail {
|
|||
|
||||
std::string GetServerVersion();
|
||||
|
||||
void LoadEpisode(std::string map_name);
|
||||
void LoadEpisode(std::string map_name, rpc::MapLayer map_layer = rpc::MapLayer::All);
|
||||
|
||||
void LoadLevelLayer(rpc::MapLayer map_layer) const;
|
||||
|
||||
void UnloadLevelLayer(rpc::MapLayer map_layer) const;
|
||||
|
||||
void CopyOpenDriveToServer(
|
||||
std::string opendrive, const rpc::OpendriveGenerationParameters & params);
|
||||
|
|
|
@ -82,9 +82,9 @@ namespace detail {
|
|||
// -- Load a new episode -----------------------------------------------------
|
||||
// ===========================================================================
|
||||
|
||||
EpisodeProxy Simulator::LoadEpisode(std::string map_name) {
|
||||
EpisodeProxy Simulator::LoadEpisode(std::string map_name, rpc::MapLayer map_layers) {
|
||||
const auto id = GetCurrentEpisode().GetId();
|
||||
_client.LoadEpisode(std::move(map_name));
|
||||
_client.LoadEpisode(std::move(map_name), map_layers);
|
||||
size_t number_of_attempts = _client.GetTimeout().milliseconds() / 10u;
|
||||
for (auto i = 0u; i < number_of_attempts; ++i) {
|
||||
using namespace std::literals::chrono_literals;
|
||||
|
|
|
@ -68,7 +68,15 @@ namespace detail {
|
|||
return LoadEpisode("");
|
||||
}
|
||||
|
||||
EpisodeProxy LoadEpisode(std::string map_name);
|
||||
EpisodeProxy LoadEpisode(std::string map_name, rpc::MapLayer map_layers = rpc::MapLayer::All);
|
||||
|
||||
void LoadLevelLayer(rpc::MapLayer map_layers) const {
|
||||
_client.LoadLevelLayer(map_layers);
|
||||
}
|
||||
|
||||
void UnloadLevelLayer(rpc::MapLayer map_layers) const {
|
||||
_client.UnloadLevelLayer(map_layers);
|
||||
}
|
||||
|
||||
EpisodeProxy LoadOpenDriveEpisode(
|
||||
std::string opendrive,
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2020 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 "MapLayer.h"
|
||||
|
||||
namespace carla {
|
||||
namespace rpc {
|
||||
|
||||
std::string MapLayerToString(MapLayer MapLayerValue)
|
||||
{
|
||||
switch(MapLayerValue)
|
||||
{
|
||||
case MapLayer::None: return "None";
|
||||
case MapLayer::Buildings: return "Buildings";
|
||||
case MapLayer::Decals: return "Decals";
|
||||
case MapLayer::Foliage: return "Foliage";
|
||||
case MapLayer::Ground: return "Ground";
|
||||
case MapLayer::ParkedVehicles: return "Parked_Vehicles";
|
||||
case MapLayer::Particles: return "Particles";
|
||||
case MapLayer::Props: return "Props";
|
||||
case MapLayer::StreetLights: return "StreetLights";
|
||||
case MapLayer::Walls: return "Walls";
|
||||
case MapLayer::All: return "All";
|
||||
default: return "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace carla
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) 2020 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 <cstdint>
|
||||
|
||||
namespace carla {
|
||||
namespace rpc {
|
||||
|
||||
using MapLayerType = uint16_t;
|
||||
|
||||
enum class MapLayer : MapLayerType
|
||||
{
|
||||
None = 0,
|
||||
Buildings = 0x1,
|
||||
Decals = 0x1 << 1,
|
||||
Foliage = 0x1 << 2,
|
||||
Ground = 0x1 << 3,
|
||||
ParkedVehicles = 0x1 << 4,
|
||||
Particles = 0x1 << 5,
|
||||
Props = 0x1 << 6,
|
||||
StreetLights = 0x1 << 7,
|
||||
Walls = 0x1 << 8,
|
||||
All = 0xFFFF,
|
||||
};
|
||||
|
||||
std::string MapLayerToString(MapLayer MapLayerValue);
|
||||
|
||||
} // namespace rpc
|
||||
} // namespace carla
|
||||
|
||||
MSGPACK_ADD_ENUM(carla::rpc::MapLayer);
|
|
@ -181,7 +181,7 @@ void export_client() {
|
|||
.def("get_world", &cc::Client::GetWorld)
|
||||
.def("get_available_maps", &GetAvailableMaps)
|
||||
.def("reload_world", CONST_CALL_WITHOUT_GIL(cc::Client, ReloadWorld))
|
||||
.def("load_world", CONST_CALL_WITHOUT_GIL_1(cc::Client, LoadWorld, std::string), (arg("map_name")))
|
||||
.def("load_world", CONST_CALL_WITHOUT_GIL_2(cc::Client, LoadWorld, std::string, rpc::MapLayer), (arg("map_name"), arg("map_layers")=rpc::MapLayer::All))
|
||||
.def("generate_opendrive_world", CONST_CALL_WITHOUT_GIL_2(cc::Client, GenerateOpenDriveWorld, std::string,
|
||||
rpc::OpendriveGenerationParameters), (arg("opendrive"), arg("parameters")=rpc::OpendriveGenerationParameters()))
|
||||
.def("start_recorder", CALL_WITHOUT_GIL_2(cc::Client, StartRecorder, std::string, bool), (arg("name"), arg("additional_data")=false))
|
||||
|
|
|
@ -206,6 +206,20 @@ void export_world() {
|
|||
.def_readonly("label", &cr::LabelledPoint::_label)
|
||||
;
|
||||
|
||||
enum_<cr::MapLayer>("MapLayer")
|
||||
.value("NONE", cr::MapLayer::None)
|
||||
.value("Buildings", cr::MapLayer::Buildings)
|
||||
.value("Decals", cr::MapLayer::Decals)
|
||||
.value("Foliage", cr::MapLayer::Foliage)
|
||||
.value("Ground", cr::MapLayer::Ground)
|
||||
.value("ParkedVehicles", cr::MapLayer::ParkedVehicles)
|
||||
.value("Particles", cr::MapLayer::Particles)
|
||||
.value("Props", cr::MapLayer::Props)
|
||||
.value("StreetLights", cr::MapLayer::StreetLights)
|
||||
.value("Walls", cr::MapLayer::Walls)
|
||||
.value("All", cr::MapLayer::All)
|
||||
;
|
||||
|
||||
#define SPAWN_ACTOR_WITHOUT_GIL(fn) +[]( \
|
||||
cc::World &self, \
|
||||
const cc::ActorBlueprint &blueprint, \
|
||||
|
@ -224,6 +238,8 @@ void export_world() {
|
|||
class_<cc::World>("World", no_init)
|
||||
.add_property("id", &cc::World::GetId)
|
||||
.add_property("debug", &cc::World::MakeDebugHelper)
|
||||
.def("load_map_layer", CONST_CALL_WITHOUT_GIL_1(cc::World, LoadLevelLayer, cr::MapLayer), arg("map_layers"))
|
||||
.def("unload_map_layer", CONST_CALL_WITHOUT_GIL_1(cc::World, UnloadLevelLayer, cr::MapLayer), arg("map_layers"))
|
||||
.def("get_blueprint_library", CONST_CALL_WITHOUT_GIL(cc::World, GetBlueprintLibrary))
|
||||
.def("get_vehicles_light_states", &GetVehiclesLightStates)
|
||||
.def("get_map", CONST_CALL_WITHOUT_GIL(cc::World, GetMap))
|
||||
|
|
|
@ -36,6 +36,9 @@ Use ARROWS or WASD keys for control.
|
|||
C : change weather (Shift+C reverse)
|
||||
Backspace : change vehicle
|
||||
|
||||
V : Select next map layer (Shift+V reverse)
|
||||
B : Load current selected map layer (Shift+B to unload)
|
||||
|
||||
R : toggle recording images to disk
|
||||
|
||||
CTRL + R : toggle recording of simulation (replacing any previous)
|
||||
|
@ -107,21 +110,23 @@ try:
|
|||
from pygame.locals import K_TAB
|
||||
from pygame.locals import K_UP
|
||||
from pygame.locals import K_a
|
||||
from pygame.locals import K_b
|
||||
from pygame.locals import K_c
|
||||
from pygame.locals import K_g
|
||||
from pygame.locals import K_d
|
||||
from pygame.locals import K_g
|
||||
from pygame.locals import K_h
|
||||
from pygame.locals import K_i
|
||||
from pygame.locals import K_l
|
||||
from pygame.locals import K_m
|
||||
from pygame.locals import K_n
|
||||
from pygame.locals import K_p
|
||||
from pygame.locals import K_q
|
||||
from pygame.locals import K_r
|
||||
from pygame.locals import K_s
|
||||
from pygame.locals import K_v
|
||||
from pygame.locals import K_w
|
||||
from pygame.locals import K_l
|
||||
from pygame.locals import K_i
|
||||
from pygame.locals import K_z
|
||||
from pygame.locals import K_x
|
||||
from pygame.locals import K_z
|
||||
from pygame.locals import K_MINUS
|
||||
from pygame.locals import K_EQUALS
|
||||
except ImportError:
|
||||
|
@ -183,6 +188,20 @@ class World(object):
|
|||
self.recording_enabled = False
|
||||
self.recording_start = 0
|
||||
self.constant_velocity_enabled = False
|
||||
self.current_map_layer = 0
|
||||
self.map_layer_names = [
|
||||
carla.MapLayer.NONE,
|
||||
carla.MapLayer.Buildings,
|
||||
carla.MapLayer.Decals,
|
||||
carla.MapLayer.Foliage,
|
||||
carla.MapLayer.Ground,
|
||||
carla.MapLayer.ParkedVehicles,
|
||||
carla.MapLayer.Particles,
|
||||
carla.MapLayer.Props,
|
||||
carla.MapLayer.StreetLights,
|
||||
carla.MapLayer.Walls,
|
||||
carla.MapLayer.All
|
||||
]
|
||||
|
||||
def restart(self):
|
||||
self.player_max_speed = 1.589
|
||||
|
@ -241,6 +260,21 @@ class World(object):
|
|||
self.hud.notification('Weather: %s' % preset[1])
|
||||
self.player.get_world().set_weather(preset[0])
|
||||
|
||||
def next_map_layer(self, reverse=False):
|
||||
self.current_map_layer += -1 if reverse else 1
|
||||
self.current_map_layer %= len(self.map_layer_names)
|
||||
selected = self.map_layer_names[self.current_map_layer]
|
||||
self.hud.notification('LayerMap selected: %s' % selected)
|
||||
|
||||
def load_map_layer(self, unload=False):
|
||||
selected = self.map_layer_names[self.current_map_layer]
|
||||
if unload:
|
||||
self.hud.notification('Unloading map layer: %s' % selected)
|
||||
self.world.unload_map_layer(selected)
|
||||
else:
|
||||
self.hud.notification('Loading map layer: %s' % selected)
|
||||
self.world.load_map_layer(selected)
|
||||
|
||||
def toggle_radar(self):
|
||||
if self.radar_sensor is None:
|
||||
self.radar_sensor = RadarSensor(self.player)
|
||||
|
@ -318,6 +352,14 @@ class KeyboardControl(object):
|
|||
world.restart()
|
||||
elif event.key == K_F1:
|
||||
world.hud.toggle_info()
|
||||
elif event.key == K_v and pygame.key.get_mods() & KMOD_SHIFT:
|
||||
world.next_map_layer(reverse=True)
|
||||
elif event.key == K_v:
|
||||
world.next_map_layer()
|
||||
elif event.key == K_b and pygame.key.get_mods() & KMOD_SHIFT:
|
||||
world.load_map_layer(unload=True)
|
||||
elif event.key == K_b:
|
||||
world.load_map_layer()
|
||||
elif event.key == K_h or (event.key == K_SLASH and pygame.key.get_mods() & KMOD_SHIFT):
|
||||
world.hud.help.toggle()
|
||||
elif event.key == K_TAB:
|
||||
|
@ -945,7 +987,6 @@ class CameraManager(object):
|
|||
if attr_name == 'range':
|
||||
self.lidar_range = float(attr_value)
|
||||
|
||||
|
||||
item.append(bp)
|
||||
self.index = None
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "Carla/Server/CarlaServer.h"
|
||||
|
||||
#include <compiler/disable-ue4-macros.h>
|
||||
#include <carla/rpc/MapLayer.h>
|
||||
#include <carla/rpc/OpendriveGenerationParameters.h>
|
||||
#include <compiler/enable-ue4-macros.h>
|
||||
|
||||
|
@ -79,17 +80,29 @@ public:
|
|||
}
|
||||
|
||||
void SetOpendriveGenerationParameters(
|
||||
const carla::rpc::OpendriveGenerationParameters & Parameters)
|
||||
const carla::rpc::OpendriveGenerationParameters & Parameters)
|
||||
{
|
||||
GenerationParameters = Parameters;
|
||||
}
|
||||
|
||||
const carla::rpc::OpendriveGenerationParameters&
|
||||
GetOpendriveGenerationParameters() const
|
||||
GetOpendriveGenerationParameters() const
|
||||
{
|
||||
return GenerationParameters;
|
||||
}
|
||||
|
||||
UFUNCTION(Category = "Carla Game Instance", BlueprintCallable)
|
||||
void SetMapLayer(int32 MapLayer)
|
||||
{
|
||||
CurrentMapLayer = MapLayer;
|
||||
}
|
||||
|
||||
UFUNCTION(Category = "Carla Game Instance", BlueprintCallable)
|
||||
int32 GetCurrentMapLayer() const
|
||||
{
|
||||
return CurrentMapLayer;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
UPROPERTY(Category = "CARLA Settings", EditAnywhere)
|
||||
|
@ -102,4 +115,7 @@ private:
|
|||
|
||||
carla::rpc::OpendriveGenerationParameters GenerationParameters;
|
||||
|
||||
UPROPERTY(Category = "CARLA Game Instance", EditAnywhere)
|
||||
int32 CurrentMapLayer = static_cast<int32>(carla::rpc::MapLayer::All);
|
||||
|
||||
};
|
||||
|
|
|
@ -8,12 +8,14 @@
|
|||
#include "Carla/Game/CarlaGameModeBase.h"
|
||||
#include "Carla/Game/CarlaHUD.h"
|
||||
#include "Engine/DecalActor.h"
|
||||
#include "Engine/LevelStreaming.h"
|
||||
|
||||
#include <compiler/disable-ue4-macros.h>
|
||||
#include "carla/opendrive/OpenDriveParser.h"
|
||||
#include "carla/road/element/RoadInfoSignal.h"
|
||||
#include <carla/rpc/EnvironmentObject.h>
|
||||
#include <carla/rpc/WeatherParameters.h>
|
||||
#include <carla/rpc/MapLayer.h>
|
||||
#include <compiler/enable-ue4-macros.h>
|
||||
|
||||
#include "Async/ParallelFor.h"
|
||||
|
@ -23,6 +25,7 @@
|
|||
#include "Kismet/KismetSystemLibrary.h"
|
||||
|
||||
namespace cr = carla::road;
|
||||
namespace crp = carla::rpc;
|
||||
namespace cre = carla::road::element;
|
||||
|
||||
ACarlaGameModeBase::ACarlaGameModeBase(const FObjectInitializer& ObjectInitializer)
|
||||
|
@ -121,6 +124,9 @@ void ACarlaGameModeBase::BeginPlay()
|
|||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
LoadMapLayer(GameInstance->GetCurrentMapLayer());
|
||||
|
||||
|
||||
if (true) { /// @todo If semantic segmentation enabled.
|
||||
check(GetWorld() != nullptr);
|
||||
ATagger::TagActorsInLevel(*GetWorld(), true);
|
||||
|
@ -350,11 +356,6 @@ TArray<FBoundingBox> ACarlaGameModeBase::GetAllBBsOfLevel(uint8 TagQueried)
|
|||
return BoundingBoxes;
|
||||
}
|
||||
|
||||
TArray<FEnvironmentObject> ACarlaGameModeBase::GetEnvironmentObjects() const
|
||||
{
|
||||
return EnvironmentObjects;
|
||||
}
|
||||
|
||||
void ACarlaGameModeBase::RegisterEnvironmentObject()
|
||||
{
|
||||
UWorld* World = GetWorld();
|
||||
|
@ -402,4 +403,86 @@ void ACarlaGameModeBase::EnableEnvironmentObjects(
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ACarlaGameModeBase::LoadMapLayer(int32 MapLayers)
|
||||
{
|
||||
const UWorld* World = GetWorld();
|
||||
|
||||
TArray<FName> LevelsToLoad;
|
||||
ConvertMapLayerMaskToMapNames(MapLayers, LevelsToLoad);
|
||||
|
||||
FLatentActionInfo LatentInfo;
|
||||
LatentInfo.UUID = 1;
|
||||
for(FName& LevelName : LevelsToLoad)
|
||||
{
|
||||
UGameplayStatics::LoadStreamLevel(World, LevelName, true, true, LatentInfo);
|
||||
LatentInfo.UUID++;
|
||||
}
|
||||
|
||||
// Register new actors and tag them
|
||||
RegisterEnvironmentObject();
|
||||
ATagger::TagActorsInLevel(*GetWorld(), true);
|
||||
|
||||
}
|
||||
|
||||
void ACarlaGameModeBase::UnLoadMapLayer(int32 MapLayers)
|
||||
{
|
||||
const UWorld* World = GetWorld();
|
||||
|
||||
TArray<FName> LevelsToLoad;
|
||||
ConvertMapLayerMaskToMapNames(MapLayers, LevelsToLoad);
|
||||
|
||||
FLatentActionInfo LatentInfo;
|
||||
LatentInfo.UUID = 1;
|
||||
for(FName& LevelName : LevelsToLoad)
|
||||
{
|
||||
UGameplayStatics::UnloadStreamLevel(World, LevelName, LatentInfo, true);
|
||||
LatentInfo.UUID++;
|
||||
}
|
||||
|
||||
// Update stored registered objects (discarding the deleted objects)
|
||||
RegisterEnvironmentObject();
|
||||
}
|
||||
|
||||
void ACarlaGameModeBase::ConvertMapLayerMaskToMapNames(int32 MapLayer, TArray<FName>& OutLevelNames)
|
||||
{
|
||||
UWorld* World = GetWorld();
|
||||
const TArray <ULevelStreaming*> Levels = World->GetStreamingLevels();
|
||||
TArray<FString> LayersToLoad;
|
||||
|
||||
// Get all the requested layers
|
||||
int32 LayerMask = 1;
|
||||
int32 AllLayersMask = static_cast<crp::MapLayerType>(crp::MapLayer::All);
|
||||
|
||||
while(LayerMask > 0)
|
||||
{
|
||||
// Convert enum to FString
|
||||
FString LayerName = UTF8_TO_TCHAR(MapLayerToString(static_cast<crp::MapLayer>(LayerMask)).c_str());
|
||||
bool included = static_cast<crp::MapLayerType>(MapLayer) & LayerMask;
|
||||
if(included)
|
||||
{
|
||||
LayersToLoad.Emplace(LayerName);
|
||||
}
|
||||
LayerMask = (LayerMask << 1) & AllLayersMask;
|
||||
}
|
||||
|
||||
// Get all the requested level maps
|
||||
for(ULevelStreaming* Level : Levels)
|
||||
{
|
||||
TArray<FString> StringArray;
|
||||
FString FullSubMapName = Level->PackageNameToLoad.ToString();
|
||||
// Discard full path, we just need the umap name
|
||||
FullSubMapName.ParseIntoArray(StringArray, TEXT("/"), false);
|
||||
FString SubMapName = StringArray[StringArray.Num() - 1];
|
||||
for(FString LayerName : LayersToLoad)
|
||||
{
|
||||
if(SubMapName.Contains(LayerName))
|
||||
{
|
||||
OutLevelNames.Emplace(FName(*SubMapName));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -6,19 +6,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Carla/Actor/CarlaActorFactory.h"
|
||||
#include "Carla/Game/CarlaEpisode.h"
|
||||
#include "Carla/Game/CarlaGameInstance.h"
|
||||
#include "Carla/Recorder/CarlaRecorder.h"
|
||||
#include "Carla/Game/TaggerDelegate.h"
|
||||
#include "Carla/OpenDrive/OpenDrive.h"
|
||||
#include "Carla/Sensor/SceneCaptureSensor.h"
|
||||
#include "Carla/Settings/CarlaSettingsDelegate.h"
|
||||
#include "Carla/Weather/Weather.h"
|
||||
#include "Carla/Traffic/TrafficLightManager.h"
|
||||
#include "Carla/Util/EnvironmentObject.h"
|
||||
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/GameModeBase.h"
|
||||
|
||||
|
@ -26,6 +13,18 @@
|
|||
#include <boost/optional.hpp>
|
||||
#include <compiler/enable-ue4-macros.h>
|
||||
|
||||
#include "Carla/Actor/CarlaActorFactory.h"
|
||||
#include "Carla/Game/CarlaEpisode.h"
|
||||
#include "Carla/Game/CarlaGameInstance.h"
|
||||
#include "Carla/Game/TaggerDelegate.h"
|
||||
#include "Carla/OpenDrive/OpenDrive.h"
|
||||
#include "Carla/Recorder/CarlaRecorder.h"
|
||||
#include "Carla/Sensor/SceneCaptureSensor.h"
|
||||
#include "Carla/Settings/CarlaSettingsDelegate.h"
|
||||
#include "Carla/Traffic/TrafficLightManager.h"
|
||||
#include "Carla/Util/EnvironmentObject.h"
|
||||
#include "Carla/Weather/Weather.h"
|
||||
|
||||
#include "CarlaGameModeBase.generated.h"
|
||||
|
||||
/// Base class for the CARLA Game Mode.
|
||||
|
@ -58,10 +57,19 @@ public:
|
|||
TArray<FBoundingBox> GetAllBBsOfLevel(uint8 TagQueried = 0);
|
||||
|
||||
UFUNCTION(Category = "Carla Game Mode", BlueprintCallable, CallInEditor, Exec)
|
||||
TArray<FEnvironmentObject> GetEnvironmentObjects() const;
|
||||
TArray<FEnvironmentObject> GetEnvironmentObjects() const
|
||||
{
|
||||
return EnvironmentObjects;
|
||||
}
|
||||
|
||||
void EnableEnvironmentObjects(const TSet<uint64>& EnvObjectIds, bool Enable);
|
||||
|
||||
UFUNCTION(Category = "Carla Game Mode", BlueprintCallable, CallInEditor, Exec)
|
||||
void LoadMapLayer(int32 MapLayers);
|
||||
|
||||
UFUNCTION(Category = "Carla Game Mode", BlueprintCallable, CallInEditor, Exec)
|
||||
void UnLoadMapLayer(int32 MapLayers);
|
||||
|
||||
protected:
|
||||
|
||||
void InitGame(const FString &MapName, const FString &Options, FString &ErrorMessage) override;
|
||||
|
@ -82,6 +90,8 @@ private:
|
|||
|
||||
void RegisterEnvironmentObject();
|
||||
|
||||
void ConvertMapLayerMaskToMapNames(int32 MapLayer, TArray<FName>& OutLevelNames);
|
||||
|
||||
UPROPERTY()
|
||||
UCarlaGameInstance *GameInstance = nullptr;
|
||||
|
||||
|
|
|
@ -25,12 +25,13 @@
|
|||
#include <carla/rpc/Command.h>
|
||||
#include <carla/rpc/CommandResponse.h>
|
||||
#include <carla/rpc/DebugShape.h>
|
||||
#include <carla/rpc/EnvironmentObject.h>
|
||||
#include <carla/rpc/EpisodeInfo.h>
|
||||
#include <carla/rpc/EpisodeSettings.h>
|
||||
#include "carla/rpc/LabelledPoint.h"
|
||||
#include <carla/rpc/LightState.h>
|
||||
#include <carla/rpc/MapInfo.h>
|
||||
#include <carla/rpc/EnvironmentObject.h>
|
||||
#include <carla/rpc/MapLayer.h>
|
||||
#include <carla/rpc/Response.h>
|
||||
#include <carla/rpc/Server.h>
|
||||
#include <carla/rpc/String.h>
|
||||
|
@ -237,13 +238,50 @@ void FCarlaServer::FPimpl::BindActions()
|
|||
return result;
|
||||
};
|
||||
|
||||
BIND_SYNC(load_new_episode) << [this](const std::string &map_name) -> R<void>
|
||||
BIND_SYNC(load_new_episode) << [this](const std::string &map_name, cr::MapLayer MapLayers) -> R<void>
|
||||
{
|
||||
REQUIRE_CARLA_EPISODE();
|
||||
|
||||
UCarlaGameInstance* GameInstance = UCarlaStatics::GetGameInstance(Episode->GetWorld());
|
||||
if (!GameInstance)
|
||||
{
|
||||
RESPOND_ERROR("unable to find CARLA game instance");
|
||||
}
|
||||
GameInstance->SetMapLayer(static_cast<int32>(MapLayers));
|
||||
|
||||
if(!Episode->LoadNewEpisode(cr::ToFString(map_name)))
|
||||
{
|
||||
RESPOND_ERROR("map not found");
|
||||
}
|
||||
|
||||
return R<void>::Success();
|
||||
};
|
||||
|
||||
BIND_SYNC(load_map_layer) << [this](cr::MapLayer MapLayers) -> R<void>
|
||||
{
|
||||
REQUIRE_CARLA_EPISODE();
|
||||
|
||||
ACarlaGameModeBase* GameMode = UCarlaStatics::GetGameMode(Episode->GetWorld());
|
||||
if (!GameMode)
|
||||
{
|
||||
RESPOND_ERROR("unable to find CARLA game mode");
|
||||
}
|
||||
GameMode->LoadMapLayer(static_cast<int32>(MapLayers));
|
||||
|
||||
return R<void>::Success();
|
||||
};
|
||||
|
||||
BIND_SYNC(unload_map_layer) << [this](cr::MapLayer MapLayers) -> R<void>
|
||||
{
|
||||
REQUIRE_CARLA_EPISODE();
|
||||
|
||||
ACarlaGameModeBase* GameMode = UCarlaStatics::GetGameMode(Episode->GetWorld());
|
||||
if (!GameMode)
|
||||
{
|
||||
RESPOND_ERROR("unable to find CARLA game mode");
|
||||
}
|
||||
GameMode->UnLoadMapLayer(static_cast<int32>(MapLayers));
|
||||
|
||||
return R<void>::Success();
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue