diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ca607e70..3a6eca476 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * The spectator will be used to load tiles and actor in Large Maps when no other actors with the rolename 'ego_vehicle' or 'hero' are present. Added the `spectator_as_ego` to the `carla.WorldSettings()` to allow users to disable this behavior. * Fixed the import script, where could use any other TilesInfo.txt if the destination folder has many * Restored gamma value to 2.2 instead of 2.4 + * Pedestrians with AI or in replayer are now faster around 10x. They have collisions disabled until they hit a vehicle. * Added API function to avoid replaying the spectator * `Client.set_replayer_ignore_spectator(bool)` * `start_replaying.py` using flag `--move-spectator` diff --git a/LibCarla/source/carla/client/Actor.cpp b/LibCarla/source/carla/client/Actor.cpp index 14f26987b..3932aabb8 100644 --- a/LibCarla/source/carla/client/Actor.cpp +++ b/LibCarla/source/carla/client/Actor.cpp @@ -84,6 +84,10 @@ namespace client { GetEpisode().Lock()->SetActorSimulatePhysics(*this, enabled); } + void Actor::SetCollisions(const bool enabled) { + GetEpisode().Lock()->SetActorCollisions(*this, enabled); + } + void Actor::SetEnableGravity(const bool enabled) { GetEpisode().Lock()->SetActorEnableGravity(*this, enabled); } diff --git a/LibCarla/source/carla/client/Actor.h b/LibCarla/source/carla/client/Actor.h index fdc892cfb..e86bf3f28 100644 --- a/LibCarla/source/carla/client/Actor.h +++ b/LibCarla/source/carla/client/Actor.h @@ -99,6 +99,9 @@ namespace client { /// Enable or disable physics simulation on this actor. void SetSimulatePhysics(bool enabled = true); + /// Enable or disable collisions on this actor. + void SetCollisions(bool enabled = true); + /// Enable or disable gravity on this actor. void SetEnableGravity(bool enabled = true); diff --git a/LibCarla/source/carla/client/WalkerAIController.cpp b/LibCarla/source/carla/client/WalkerAIController.cpp index e0661e642..55cd0587d 100644 --- a/LibCarla/source/carla/client/WalkerAIController.cpp +++ b/LibCarla/source/carla/client/WalkerAIController.cpp @@ -23,6 +23,9 @@ namespace client { auto nav = GetEpisode().Lock()->GetNavigation(); if (nav != nullptr) { nav->AddWalker(walker->GetId(), walker->GetLocation()); + // disable physics and collision of walker actor + GetEpisode().Lock()->SetActorSimulatePhysics(*walker, false); + GetEpisode().Lock()->SetActorCollisions(*walker, false); } } } diff --git a/LibCarla/source/carla/client/detail/Client.cpp b/LibCarla/source/carla/client/detail/Client.cpp index b335a7d87..0733b1f7d 100644 --- a/LibCarla/source/carla/client/detail/Client.cpp +++ b/LibCarla/source/carla/client/detail/Client.cpp @@ -412,6 +412,10 @@ namespace detail { _pimpl->CallAndWait("set_actor_simulate_physics", actor, enabled); } + void Client::SetActorCollisions(rpc::ActorId actor, const bool enabled) { + _pimpl->CallAndWait("set_actor_collisions", actor, enabled); + } + void Client::SetActorEnableGravity(rpc::ActorId actor, const bool enabled) { _pimpl->AsyncCall("set_actor_enable_gravity", actor, enabled); } diff --git a/LibCarla/source/carla/client/detail/Client.h b/LibCarla/source/carla/client/detail/Client.h index 21f3ca310..8f44b962f 100644 --- a/LibCarla/source/carla/client/detail/Client.h +++ b/LibCarla/source/carla/client/detail/Client.h @@ -236,6 +236,10 @@ namespace detail { rpc::ActorId actor, bool enabled); + void SetActorCollisions( + rpc::ActorId actor, + bool enabled); + void SetActorEnableGravity( rpc::ActorId actor, bool enabled); diff --git a/LibCarla/source/carla/client/detail/Simulator.h b/LibCarla/source/carla/client/detail/Simulator.h index cc8082586..bd600740f 100644 --- a/LibCarla/source/carla/client/detail/Simulator.h +++ b/LibCarla/source/carla/client/detail/Simulator.h @@ -431,6 +431,10 @@ namespace detail { _client.SetActorSimulatePhysics(actor.GetId(), enabled); } + void SetActorCollisions(Actor &actor, bool enabled) { + _client.SetActorCollisions(actor.GetId(), enabled); + } + void SetActorEnableGravity(Actor &actor, bool enabled) { _client.SetActorEnableGravity(actor.GetId(), enabled); } diff --git a/LibCarla/source/carla/client/detail/WalkerNavigation.cpp b/LibCarla/source/carla/client/detail/WalkerNavigation.cpp index bb46fe7ed..dbce47232 100644 --- a/LibCarla/source/carla/client/detail/WalkerNavigation.cpp +++ b/LibCarla/source/carla/client/detail/WalkerNavigation.cpp @@ -57,8 +57,24 @@ namespace detail { commands.emplace_back(Cmd::ApplyWalkerState{ handle.walker, trans, speed }); } } - _client.ApplyBatchSync(std::move(commands), false); + + // check if any agent has been killed + bool alive; + for (auto handle : *walkers) { + // get the agent state + if (_nav.IsWalkerAlive(handle.walker, alive)) { + if (!alive) { + _client.SetActorCollisions(handle.walker, true); + // remove from the crowd + _nav.RemoveAgent(handle.walker); + // destroy the controller + _client.DestroyActor(handle.controller); + // unregister from list + UnregisterWalker(handle.walker, handle.controller); + } + } + } } void WalkerNavigation::CheckIfWalkerExist(std::vector walkers, const EpisodeState &state) { diff --git a/LibCarla/source/carla/nav/Navigation.cpp b/LibCarla/source/carla/nav/Navigation.cpp index debca0be5..3cab1a370 100644 --- a/LibCarla/source/carla/nav/Navigation.cpp +++ b/LibCarla/source/carla/nav/Navigation.cpp @@ -862,7 +862,8 @@ namespace nav { std::lock_guard lock(_mutex); ag = _crowd->getAgent(i); } - if (!ag->active || ag->paused) { + + if (!ag->active || ag->paused || ag->dead) { continue; } @@ -1203,5 +1204,39 @@ namespace nav { return true; } + bool Navigation::IsWalkerAlive(ActorId id, bool &alive) { + // check if all is ready + if (!_ready) { + return false; + } + + DEBUG_ASSERT(_crowd != nullptr); + + // get the internal index + auto it = _mapped_walkers_id.find(id); + if (it == _mapped_walkers_id.end()) { + return false; + } + + // get the index found + int index = it->second; + if (index == -1) { + return false; + } + + // get the walker + const dtCrowdAgent *agent; + { + // critical section, force single thread running this + std::lock_guard lock(_mutex); + agent = _crowd->getAgent(index); + } + + // mark + alive = !agent->dead; + + return true; + } + } // namespace nav } // namespace carla diff --git a/LibCarla/source/carla/nav/Navigation.h b/LibCarla/source/carla/nav/Navigation.h index be35d740d..b918a179c 100644 --- a/LibCarla/source/carla/nav/Navigation.h +++ b/LibCarla/source/carla/nav/Navigation.h @@ -108,6 +108,8 @@ namespace nav { bool HasVehicleNear(ActorId id, float distance, carla::geom::Location direction); /// make agent look at some location bool SetWalkerLookAt(ActorId id, carla::geom::Location location); + /// return if the agent has been killed by a vehicle + bool Navigation::IsWalkerAlive(ActorId id, bool &alive); dtCrowd *GetCrowd() { return _crowd; }; diff --git a/PythonAPI/carla/source/libcarla/Actor.cpp b/PythonAPI/carla/source/libcarla/Actor.cpp index 1c6271057..f0c1b670b 100644 --- a/PythonAPI/carla/source/libcarla/Actor.cpp +++ b/PythonAPI/carla/source/libcarla/Actor.cpp @@ -124,6 +124,7 @@ void export_actor() { .def("add_angular_impulse", &cc::Actor::AddAngularImpulse, (arg("angular_impulse"))) .def("add_torque", &cc::Actor::AddTorque, (arg("torque"))) .def("set_simulate_physics", &cc::Actor::SetSimulatePhysics, (arg("enabled") = true)) + .def("set_collisions", &cc::Actor::SetCollisions, (arg("enabled") = true)) .def("set_enable_gravity", &cc::Actor::SetEnableGravity, (arg("enabled") = true)) .def("destroy", CALL_WITHOUT_GIL(cc::Actor, Destroy)) .def(self_ns::str(self_ns::self)) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/CarlaActor.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/CarlaActor.cpp index b2739f8ee..cfea3ea83 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/CarlaActor.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/CarlaActor.cpp @@ -17,6 +17,7 @@ #include "Carla/Vehicle/MovementComponents/ChronoMovementComponent.h" #include "Carla/Traffic/TrafficLightBase.h" #include "Carla/Game/CarlaStatics.h" +#include "Components/CapsuleComponent.h" #include #include @@ -578,6 +579,18 @@ ECarlaServerResponse FCarlaActor::SetActorSimulatePhysics(bool bEnabled) return ECarlaServerResponse::Success; } +ECarlaServerResponse FCarlaActor::SetActorCollisions(bool bEnabled) +{ + if (IsDormant()) + { + } + else + { + GetActor()->SetActorEnableCollision(bEnabled); + } + return ECarlaServerResponse::Success; +} + ECarlaServerResponse FCarlaActor::SetActorEnableGravity(bool bEnabled) { if (IsDormant()) @@ -1201,12 +1214,15 @@ ECarlaServerResponse FWalkerActor::SetWalkerState( { FVector NewLocation = Transform.GetLocation(); FVector CurrentLocation = GetActorGlobalLocation(); - NewLocation.Z += 90.0f; // move point up because in Unreal walker is centered in the middle height - // if difference between Z position is small, then we keep current, otherwise we set the new one - // (to avoid Z fighting position and falling pedestrians) - if (NewLocation.Z - CurrentLocation.Z < 100.0f) - NewLocation.Z = CurrentLocation.Z; + // adjust position up by half of capsule height + // (because in Unreal walker is centered at the capsule middle, + // while Recast uses the bottom point) + UCapsuleComponent* Capsule = Cast(GetActor()->GetRootComponent()); + if (Capsule) + { + NewLocation.Z += Capsule->GetScaledCapsuleHalfHeight(); + } FTransform NewTransform = Transform; NewTransform.SetLocation(NewLocation); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/CarlaActor.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/CarlaActor.h index b47969c87..0f3903a05 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/CarlaActor.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Actor/CarlaActor.h @@ -224,6 +224,8 @@ public: ECarlaServerResponse AddActorTorque(const FVector& Torque); virtual ECarlaServerResponse SetActorSimulatePhysics(bool bEnabled); + + virtual ECarlaServerResponse SetActorCollisions(bool bEnabled); virtual ECarlaServerResponse SetActorEnableGravity(bool bEnabled); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.h index 0cf92dc4d..4694c3335 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.h @@ -350,6 +350,8 @@ private: bool SetActorSimulatePhysics(FCarlaActor &CarlaActor, bool bEnabled); + bool SetActorCollisions(FCarlaActor &CarlaActor, bool bEnabled); + void TickTimers(float DeltaSeconds) { ElapsedGameTime += DeltaSeconds; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp index 0e0122c85..918d3aa51 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp @@ -30,7 +30,8 @@ void CarlaReplayer::Stop(bool bKeepActors) Helper.ProcessReplayerFinish(bKeepActors, IgnoreHero, IsHeroMap); } - File.close(); + if (File.is_open()) + File.close(); } bool CarlaReplayer::ReadHeader() diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp index 0588ffcd5..3ca4c4b4f 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp @@ -218,20 +218,26 @@ std::pair CarlaReplayerHelper::ProcessReplayerEventAdd( if (result.first != 0) { // disable physics and autopilot on vehicles - if (result.second->GetActorType() == FCarlaActor::ActorType::Vehicle) + if (result.second->GetActorType() == FCarlaActor::ActorType::Vehicle || + result.second->GetActorType() == FCarlaActor::ActorType::Walker) { // ignore hero ? if (!(bIgnoreHero && IsHero)) { // disable physics SetActorSimulatePhysics(result.second, false); - // disable autopilot - SetActorAutopilot(result.second, false, false); + // disable collisions + result.second->GetActor()->SetActorEnableCollision(false); + // disable autopilot for vehicles + if (result.second->GetActorType() == FCarlaActor::ActorType::Vehicle) + SetActorAutopilot(result.second, false, false); } else { - // reenable physics just in case + // enable physics just in case SetActorSimulatePhysics(result.second, true); + // enable collisions + result.second->GetActor()->SetActorEnableCollision(true); } } return std::make_pair(result.first, result.second->GetActorId()); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp index c1552ef34..6d853a266 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp @@ -55,7 +55,7 @@ void FPixelReader::WritePixelsToBuffer( RHICmdList.GetRenderQueryResult(Query, OldAbsTime, true); } - AsyncTask(ENamedThreads::AnyNormalThreadNormalTask, [=, Readback=std::move(BackBufferReadback)]() mutable { + AsyncTask(ENamedThreads::ActualRenderingThread, [=, Readback=std::move(BackBufferReadback)]() mutable { { TRACE_CPUPROFILER_EVENT_SCOPE_STR("Wait GPU transfer"); while (!Readback->IsReady()) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp index 8c26b5bc6..42ad45835 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/CarlaServer.cpp @@ -1384,6 +1384,31 @@ void FCarlaServer::FPimpl::BindActions() return R::Success(); }; + BIND_SYNC(set_actor_collisions) << [this]( + cr::ActorId ActorId, + bool bEnabled) -> R + { + REQUIRE_CARLA_EPISODE(); + FCarlaActor* CarlaActor = Episode->FindCarlaActor(ActorId); + if (!CarlaActor) + { + return RespondError( + "set_actor_collisions", + ECarlaServerResponse::ActorNotFound, + " Actor Id: " + FString::FromInt(ActorId)); + } + ECarlaServerResponse Response = + CarlaActor->SetActorCollisions(bEnabled); + if (Response != ECarlaServerResponse::Success) + { + return RespondError( + "set_actor_collisions", + Response, + " Actor Id: " + FString::FromInt(ActorId)); + } + return R::Success(); + }; + BIND_SYNC(set_actor_enable_gravity) << [this]( cr::ActorId ActorId, bool bEnabled) -> R diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp index f8960fc2e..1580e7180 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Vehicle/CarlaWheeledVehicle.cpp @@ -827,8 +827,21 @@ void ACarlaWheeledVehicle::ShowDebugTelemetry(bool Enabled) void ACarlaWheeledVehicle::SetVehicleLightState(const FVehicleLightState &LightState) { - InputControl.LightState = LightState; - RefreshLightState(LightState); + if (LightState.Position != InputControl.LightState.Position || + LightState.LowBeam != InputControl.LightState.LowBeam || + LightState.HighBeam != InputControl.LightState.HighBeam || + LightState.Brake != InputControl.LightState.Brake || + LightState.RightBlinker != InputControl.LightState.RightBlinker || + LightState.LeftBlinker != InputControl.LightState.LeftBlinker || + LightState.Reverse != InputControl.LightState.Reverse || + LightState.Fog != InputControl.LightState.Fog || + LightState.Interior != InputControl.LightState.Interior || + LightState.Special1 != InputControl.LightState.Special1 || + LightState.Special2 != InputControl.LightState.Special2) + { + InputControl.LightState = LightState; + RefreshLightState(LightState); + } } void ACarlaWheeledVehicle::SetFailureState(const carla::rpc::VehicleFailureState &InFailureState) diff --git a/Util/BuildTools/Setup.sh b/Util/BuildTools/Setup.sh index f04508d63..5d45be0af 100755 --- a/Util/BuildTools/Setup.sh +++ b/Util/BuildTools/Setup.sh @@ -274,8 +274,8 @@ unset GTEST_BASENAME # -- Get Recast&Detour and compile it with libc++ ------------------------------ # ============================================================================== -RECAST_HASH=0b13b0 -RECAST_COMMIT=0b13b0d288ac96fdc5347ee38299511c6e9400db +RECAST_HASH=22dfcb +RECAST_COMMIT=22dfcb46204df1a07f696ae3d9efc76f718ea531 RECAST_BASENAME=recast-${RECAST_HASH}-${CXX_TAG} RECAST_INCLUDE=${PWD}/${RECAST_BASENAME}-install/include diff --git a/Util/InstallersWin/install_recast.bat b/Util/InstallersWin/install_recast.bat index 54d2bcaf7..4a7e9b08d 100644 --- a/Util/InstallersWin/install_recast.bat +++ b/Util/InstallersWin/install_recast.bat @@ -35,8 +35,8 @@ rem If not set set the build dir to the current dir if "%BUILD_DIR%" == "" set BUILD_DIR=%~dp0 if not "%BUILD_DIR:~-1%"=="\" set BUILD_DIR=%BUILD_DIR%\ -set RECAST_HASH=0b13b0 -set RECAST_COMMIT=0b13b0d288ac96fdc5347ee38299511c6e9400db +set RECAST_HASH=22dfcb +set RECAST_COMMIT=22dfcb46204df1a07f696ae3d9efc76f718ea531 set RECAST_SRC=recast-%RECAST_HASH%-src set RECAST_SRC_DIR=%BUILD_DIR%%RECAST_SRC%\ set RECAST_INSTALL=recast-%RECAST_HASH%-install