From be37d2233504e77a0b69e98bca8c656cef518336 Mon Sep 17 00:00:00 2001 From: bernatx Date: Tue, 5 Mar 2019 18:01:17 +0100 Subject: [PATCH 01/14] Added replayer speed (time factor for slow/fast motion) --- CHANGELOG.md | 2 + Docs/python_api.md | 1 + Docs/python_api_tutorial.md | 10 +++ LibCarla/source/carla/client/Client.h | 4 ++ .../source/carla/client/detail/Client.cpp | 4 ++ LibCarla/source/carla/client/detail/Client.h | 2 + .../source/carla/client/detail/Simulator.h | 4 ++ PythonAPI/carla/source/libcarla/Client.cpp | 1 + PythonAPI/examples/start_replaying.py | 7 ++ PythonAPI/set_replayer_speed.py | 70 +++++++++++++++++++ .../Source/Carla/Recorder/CarlaRecorder.cpp | 5 ++ .../Source/Carla/Recorder/CarlaRecorder.h | 1 + .../Source/Carla/Recorder/CarlaReplayer.cpp | 19 +++-- .../Source/Carla/Recorder/CarlaReplayer.h | 5 ++ .../Carla/Recorder/CarlaReplayerHelper.cpp | 20 ++++-- .../Source/Carla/Server/TheNewCarlaServer.cpp | 7 ++ 16 files changed, 153 insertions(+), 9 deletions(-) create mode 100644 PythonAPI/set_replayer_speed.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c459fcd5..22a7daa45 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## CARLA 0.9.5 + * Added playback speed (slow/fast motion) for the replayer + * We can use an absolute path for the recorded files (to choose where to 'write to' or 'read from') * New Town07, rural environment with narrow roads * Reworked OpenDRIVE parser and waypoints API - Fixed several situations in which the XODR was incorrectly parsed diff --git a/Docs/python_api.md b/Docs/python_api.md index ca93be48e..65e8c9c36 100644 --- a/Docs/python_api.md +++ b/Docs/python_api.md @@ -20,6 +20,7 @@ - `show_recorder_file_info(string filename)` - `show_recorder_collisions(string filename, char category1, char category2)` - `show_recorder_actors_blocked(string filename, float min_time, float min_distance)` +- `set_replayer_speed(float time_factor)` - `apply_batch(commands, do_tick=False)` - `apply_batch_sync(commands, do_tick=False) -> list(carla.command.Response)` diff --git a/Docs/python_api_tutorial.md b/Docs/python_api_tutorial.md index 3f332b4b8..37c12a852 100644 --- a/Docs/python_api_tutorial.md +++ b/Docs/python_api_tutorial.md @@ -449,6 +449,16 @@ client.replay_file("recording01.log", start, duration, camera) * **duration**: we can say how many seconds we want to play. If the simulation has not reached the end, then all actors will have autopilot enabled automatically. The intention here is to allow for replaying a piece of a simulation and then let all actors start driving in autopilot again. * **camera**: we can specify the Id of an actor and then the camera will follow that actor while replaying. Continue reading to know which Id has an actor. +We can specify the speed for the replayer at any moment, using the next API: + +```py +client.set_replayer_speed(2.0) +``` +A value greater than 1.0 will play in fast motion, and a value below 1.0 will play in slow motion, being 1.0 the default value for normal playback. +As a performance trick, with values over 2.0 the interpolation of positions is disabled. + +The call of this API will not stop the replayer in course, it will change just the speed, so you can change that several times while the replayer is running. + We can know details about a recorded simulation, using this API: ```py diff --git a/LibCarla/source/carla/client/Client.h b/LibCarla/source/carla/client/Client.h index fe248e97f..e4a169329 100644 --- a/LibCarla/source/carla/client/Client.h +++ b/LibCarla/source/carla/client/Client.h @@ -84,6 +84,10 @@ namespace client { return _simulator->ReplayFile(name, start, duration, follow_id); } + void SetReplayerSpeed(double time_factor) { + _simulator->SetReplayerSpeed(time_factor); + } + void ApplyBatch( std::vector commands, bool do_tick_cue = false) const { diff --git a/LibCarla/source/carla/client/detail/Client.cpp b/LibCarla/source/carla/client/detail/Client.cpp index 0c7ba2b79..70dc07703 100644 --- a/LibCarla/source/carla/client/detail/Client.cpp +++ b/LibCarla/source/carla/client/detail/Client.cpp @@ -291,6 +291,10 @@ namespace detail { return _pimpl->CallAndWait("replay_file", name, start, duration, follow_id); } + void Client::SetReplayerSpeed(double time_factor) { + _pimpl->AsyncCall("set_replayer_speed", time_factor); + } + void Client::SubscribeToStream( const streaming::Token &token, std::function callback) { diff --git a/LibCarla/source/carla/client/detail/Client.h b/LibCarla/source/carla/client/detail/Client.h index dcd021558..eca24ee47 100644 --- a/LibCarla/source/carla/client/detail/Client.h +++ b/LibCarla/source/carla/client/detail/Client.h @@ -182,6 +182,8 @@ namespace detail { std::string ReplayFile(std::string name, double start, double duration, uint32_t follow_id); + void SetReplayerSpeed(double time_factor); + void SubscribeToStream( const streaming::Token &token, std::function callback); diff --git a/LibCarla/source/carla/client/detail/Simulator.h b/LibCarla/source/carla/client/detail/Simulator.h index c468cff29..b3b9c3bde 100644 --- a/LibCarla/source/carla/client/detail/Simulator.h +++ b/LibCarla/source/carla/client/detail/Simulator.h @@ -293,6 +293,10 @@ namespace detail { return _client.ReplayFile(std::move(name), start, duration, follow_id); } + void SetReplayerSpeed(double time_factor) { + _client.SetReplayerSpeed(time_factor); + } + /// @} // ========================================================================= /// @name Operations with sensors diff --git a/PythonAPI/carla/source/libcarla/Client.cpp b/PythonAPI/carla/source/libcarla/Client.cpp index 146493ee3..4b51f5f20 100644 --- a/PythonAPI/carla/source/libcarla/Client.cpp +++ b/PythonAPI/carla/source/libcarla/Client.cpp @@ -68,6 +68,7 @@ void export_client() { .def("show_recorder_collisions", CALL_WITHOUT_GIL_3(cc::Client, ShowRecorderCollisions, std::string, char, char), (arg("name"), arg("type1"), arg("type2"))) .def("show_recorder_actors_blocked", CALL_WITHOUT_GIL_3(cc::Client, ShowRecorderActorsBlocked, std::string, float, float), (arg("name"), arg("min_time"), arg("min_distance"))) .def("replay_file", CALL_WITHOUT_GIL_4(cc::Client, ReplayFile, std::string, float, float, int), (arg("name"), arg("time_start"), arg("duration"), arg("follow_id"))) + .def("set_replayer_speed", &cc::Client::SetReplayerSpeed, (arg("time_factor"))) .def("apply_batch", &ApplyBatchCommands, (arg("commands"), arg("do_tick")=false)) .def("apply_batch_sync", &ApplyBatchCommandsSync, (arg("commands"), arg("do_tick")=false)) ; diff --git a/PythonAPI/examples/start_replaying.py b/PythonAPI/examples/start_replaying.py index a574ba0bb..75adc3a23 100755 --- a/PythonAPI/examples/start_replaying.py +++ b/PythonAPI/examples/start_replaying.py @@ -61,6 +61,12 @@ def main(): default=0, type=int, help='camera follows an actor (ex: 82)') + argparser.add_argument( + '-x', '--speed', + metavar='X', + default=1.0, + type=float, + help='time factor(default 1.0)') args = argparser.parse_args() try: @@ -68,6 +74,7 @@ def main(): client = carla.Client(args.host, args.port) client.set_timeout(60.0) + client.set_replayer_speed(args.speed) print(client.replay_file(args.recorder_filename, args.start, args.duration, args.camera)) finally: diff --git a/PythonAPI/set_replayer_speed.py b/PythonAPI/set_replayer_speed.py new file mode 100644 index 000000000..53f465a3c --- /dev/null +++ b/PythonAPI/set_replayer_speed.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python + +# 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 . + +import glob +import os +import sys + +try: + sys.path.append(glob.glob('**/*%d.%d-%s.egg' % ( + sys.version_info.major, + sys.version_info.minor, + 'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0]) +except IndexError: + pass + +import carla + +import argparse +import random +import time + + +def main(): + + argparser = argparse.ArgumentParser( + description=__doc__) + argparser.add_argument( + '--host', + metavar='H', + default='127.0.0.1', + help='IP of the host server (default: 127.0.0.1)') + argparser.add_argument( + '-p', '--port', + metavar='P', + default=2000, + type=int, + help='TCP port to listen to (default: 2000)') + argparser.add_argument( + '-x', '--speed', + metavar='X', + default=1.0, + type=float, + help='time factor(default 1.0)') + args = argparser.parse_args() + + try: + + client = carla.Client(args.host, args.port) + client.set_timeout(2.0) + + # client.load_world("Town03") + + client.set_replayer_speed(args.speed) + + finally: + pass + +if __name__ == '__main__': + + try: + main() + except KeyboardInterrupt: + pass + finally: + print('\ndone.') diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp index 8a54fe0d7..fcfb557cc 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp @@ -45,6 +45,11 @@ std::string ACarlaRecorder::ReplayFile(std::string Path, std::string Name, doubl return Replayer.ReplayFile(Path + Name, TimeStart, Duration, FollowId); } +inline void ACarlaRecorder::SetReplayerSpeed(double TimeFactor) +{ + return Replayer.SetSpeed(TimeFactor); +} + void ACarlaRecorder::Tick(float DeltaSeconds) { Super::Tick(DeltaSeconds); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h index 94a7943b6..9f77f933a 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h @@ -103,6 +103,7 @@ public: std::string ShowFileCollisions(std::string Path, std::string Name, char Type1, char Type2); std::string ShowFileActorsBlocked(std::string Path, std::string Name, double MinTime = 30, double MinDistance = 10); std::string ReplayFile(std::string Path, std::string Name, double TimeStart, double Duration, uint32_t FollowId); + void SetReplayerSpeed(double TimeFactor); void Tick(float DeltaSeconds) final; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp index 24705fe2a..d02a8f4c8 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp @@ -467,13 +467,18 @@ void CarlaReplayer::UpdatePositions(double Per) auto Result = TempMap.find(CurrPos[i].DatabaseId); if (Result != TempMap.end()) { - // interpolate - InterpolatePosition(PrevPos[Result->second], CurrPos[i], Per); + // check if time factor is high + if (TimeFactor >= 2.0) + // assign first position + InterpolatePosition(PrevPos[Result->second], CurrPos[i], 0.0); + else + // interpolate + InterpolatePosition(PrevPos[Result->second], CurrPos[i], Per); } else { // assign last position (we don't have previous one) - InterpolatePosition(CurrPos[i], CurrPos[i], 0); + InterpolatePosition(CurrPos[i], CurrPos[i], 0.0); } // move the camera to follow this actor if required @@ -502,8 +507,14 @@ void CarlaReplayer::Tick(float Delta) // check if there are events to process if (Enabled) { - ProcessToTime(Delta); + ProcessToTime(Delta * TimeFactor); } // UE_LOG(LogCarla, Log, TEXT("Replayer tick")); } + +// speed (time factor) +inline void CarlaReplayer::SetSpeed(double NewTimeFactor) +{ + TimeFactor = NewTimeFactor; +} \ No newline at end of file diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h index a819d4721..e286eb245 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h @@ -60,6 +60,9 @@ public: Helper.SetEpisode(ThisEpisode); } + // playback speed (time factor) + void SetSpeed(double NewTimeFactor); + // tick for the replayer void Tick(float Time); @@ -85,6 +88,8 @@ private: CarlaReplayerHelper Helper; // follow camera uint32_t FollowId; + // speed (time factor) + double TimeFactor { 1.0 }; // utils bool ReadHeader(); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp index 8dc74acc9..00b1ac5c2 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp @@ -228,11 +228,21 @@ bool CarlaReplayerHelper::ProcessReplayerPosition(CarlaRecorderPosition Pos1, Ca AActor *Actor = Episode->GetActorRegistry().Find(Pos1.DatabaseId).GetActor(); if (Actor && !Actor->IsPendingKill()) { - // interpolate transform - FVector Location = FMath::Lerp(FVector(Pos1.Location), FVector(Pos2.Location), Per); - FRotator Rotation = FMath::Lerp(FRotator::MakeFromEuler(Pos1.Rotation), FRotator::MakeFromEuler(Pos2.Rotation), Per); - FTransform Trans(Rotation, Location, FVector(1, 1, 1)); - Actor->SetActorTransform(Trans, false, nullptr, ETeleportType::TeleportPhysics); + // check to assign first position or interpolate between both + if (Per == 0.0) + { + // assign position 1 + FTransform Trans(FRotator::MakeFromEuler(Pos1.Rotation), FVector(Pos1.Location), FVector(1, 1, 1)); + Actor->SetActorTransform(Trans, false, nullptr, ETeleportType::TeleportPhysics); + } + else + { + // interpolate positions + FVector Location = FMath::Lerp(FVector(Pos1.Location), FVector(Pos2.Location), Per); + FRotator Rotation = FMath::Lerp(FRotator::MakeFromEuler(Pos1.Rotation), FRotator::MakeFromEuler(Pos2.Rotation), Per); + FTransform Trans(Rotation, Location, FVector(1, 1, 1)); + Actor->SetActorTransform(Trans, false, nullptr, ETeleportType::TeleportPhysics); + } // reset velocities ResetVelocities(Actor); return true; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp index ec36c6c69..cdfa8c706 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp @@ -761,6 +761,13 @@ void FTheNewCarlaServer::FPimpl::BindActions() follow_id)); }; + BIND_SYNC(set_replayer_speed) << [this](double time_factor) -> R + { + REQUIRE_CARLA_EPISODE(); + Episode->GetRecorder()->SetReplayerSpeed(time_factor); + return R::Success(); + }; + // ~~ Draw debug shapes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BIND_SYNC(draw_debug_shape) << [this](const cr::DebugShape &shape) -> R From 702474f764bbfb5771abb0dd0193600d7446d5a3 Mon Sep 17 00:00:00 2001 From: bernatx Date: Fri, 8 Mar 2019 11:16:01 +0100 Subject: [PATCH 02/14] Replayer now will load the required map automatically. Also a bug fix. --- .../Carla/Source/Carla/Game/CarlaEpisode.cpp | 3 + .../Source/Carla/Recorder/CarlaReplayer.cpp | 168 +++++++++++++----- .../Source/Carla/Recorder/CarlaReplayer.h | 15 ++ 3 files changed, 138 insertions(+), 48 deletions(-) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.cpp index 67558dc99..932d156d5 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.cpp @@ -200,6 +200,9 @@ void UCarlaEpisode::InitializeAtBeginPlay() ActorDispatcher->RegisterActor(*Actor, Description); } } + + // check if replayer is waiting to autostart + Recorder->GetReplayer()->CheckPlayAfterMapLoaded(); } void UCarlaEpisode::EndPlay(void) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp index d02a8f4c8..3d26474c9 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp @@ -10,6 +10,9 @@ #include #include +// structure to save replaying info when need to load a new map (static member by now) +CarlaReplayer::PlayAfterLoadMap CarlaReplayer::Autoplay { false, "", "", 0.0, 0.0, 0, 1.0 }; + void CarlaReplayer::Stop(bool bKeepActors) { if (Enabled) @@ -22,20 +25,11 @@ void CarlaReplayer::Stop(bool bKeepActors) ProcessToTime(TotalTime); } - File.close(); - // callback Helper.ProcessReplayerFinish(bKeepActors); } - if (!bKeepActors) - { - UE_LOG(LogCarla, Log, TEXT("Replayer stop")); - } - else - { - UE_LOG(LogCarla, Log, TEXT("Replayer stop (keeping actors)")); - } + File.close(); } bool CarlaReplayer::ReadHeader() @@ -73,8 +67,6 @@ void CarlaReplayer::Rewind(void) // read geneal Info RecInfo.Read(File); - - // UE_LOG(LogCarla, Log, TEXT("Replayer rewind")); } // read last frame in File and return the Total time recorded @@ -126,49 +118,126 @@ std::string CarlaReplayer::ReplayFile(std::string Filename, double TimeStart, do if (!File.is_open()) { Info << "File " << Filename << " not found on server\n"; + Stop(); return Info.str(); } // from start Rewind(); + // check to load map if different + if (Episode->GetMapName() != RecInfo.Mapfile) + { + if (!Episode->LoadNewEpisode(RecInfo.Mapfile)) + { + Info << "Could not load mapfile " << TCHAR_TO_UTF8(*RecInfo.Mapfile) << std::endl; + Stop(); + return Info.str(); + } + Info << "Loading map " << TCHAR_TO_UTF8(*RecInfo.Mapfile) << std::endl; + Info << "Replayer will start after map is loaded..." << std::endl; + + // prepare autoplay after map is loaded + Autoplay.Enabled = true; + Autoplay.Filename = Filename; + Autoplay.Mapfile = RecInfo.Mapfile; + Autoplay.TimeStart = TimeStart; + Autoplay.Duration = Duration; + Autoplay.FollowId = FollowId; + Autoplay.TimeFactor = TimeFactor; + } + + // get Total time of recorder + TotalTime = GetTotalTime(); + Info << "Total time recorded: " << TotalTime << std::endl; + + // set time to start replayer + if (TimeStart < 0.0f) + { + TimeStart = TotalTime + TimeStart; + if (TimeStart < 0.0f) + TimeStart = 0.0f; + } + + // set time to stop replayer + if (Duration > 0.0f) + TimeToStop = TimeStart + Duration; + else + TimeToStop = TotalTime; + + Info << "Replaying from " << TimeStart << " s - " << TimeToStop << " s (" << TotalTime << " s)" << + std::endl; + + // set the follow Id + FollowId = ThisFollowId; + + // if we don't need to load a new map, then start + if (!Autoplay.Enabled) + { + // process all events until the time + ProcessToTime(TimeStart); + // mark as enabled + Enabled = true; + } + + return Info.str(); +} + +void CarlaReplayer::CheckPlayAfterMapLoaded(void) +{ + + // check if the autoplay is enabled (means waiting until map is loaded) + if (!Autoplay.Enabled) + return; + + // disable + Autoplay.Enabled = false; + + // check to stop if we are replaying another + if (Enabled) + { + Stop(); + } + + // try to open + File.open(Autoplay.Filename, std::ios::binary); + if (!File.is_open()) + { + return; + } + + // from start + Rewind(); + // get Total time of recorder TotalTime = GetTotalTime(); - Info << "Total time recorded: " << TotalTime << std::endl; + // set time to start replayer + double TimeStart = Autoplay.TimeStart; if (TimeStart < 0.0f) { - TimeStart = TotalTime + TimeStart; + TimeStart = TotalTime + Autoplay.TimeStart; if (TimeStart < 0.0f) - { TimeStart = 0.0f; - } } + // set time to stop replayer - if (Duration > 0.0f) - { - TimeToStop = TimeStart + Duration; - } + if (Autoplay.Duration > 0.0f) + TimeToStop = TimeStart + Autoplay.Duration; else - { TimeToStop = TotalTime; - } - Info << "Replaying from " << TimeStart << " s - " << TimeToStop << " s (" << TotalTime << " s)" << - std::endl; + + // set the follow Id + FollowId = Autoplay.FollowId; + + // apply time factor + TimeFactor = Autoplay.TimeFactor; // process all events until the time ProcessToTime(TimeStart); - // set the follow Id - if (ThisFollowId != 0) - FollowId = ThisFollowId; - else - FollowId = 0; - // mark as enabled Enabled = true; - - return Info.str(); } void CarlaReplayer::ProcessToTime(double Time) @@ -302,18 +371,15 @@ void CarlaReplayer::ProcessEventsAdd(void) if (!EventAdd.Description.Id.StartsWith("sensor.")) { // show log - /* - Info.str(""); - Info << " Create " << EventAdd.DatabaseId << ": " << TCHAR_TO_UTF8(*EventAdd.Description.Id) << " (" << - EventAdd.Description.UId << ") at (" << EventAdd.Location.X << ", " << - EventAdd.Location.Y << ", " << EventAdd.Location.Z << ")" << std::endl; - for (auto &Att : EventAdd.Description.Attributes) - { - Info << " " << TCHAR_TO_UTF8(*Att.Id) << " = " << TCHAR_TO_UTF8(*Att.Value) << std::endl; - } - - UE_LOG(LogCarla, Log, "%s", Info.str().c_str()); - */ + // Info.str(""); + // Info << " Create " << EventAdd.DatabaseId << ": " << TCHAR_TO_UTF8(*EventAdd.Description.Id) << " (" << + // EventAdd.Description.UId << ") at (" << EventAdd.Location.X << ", " << + // EventAdd.Location.Y << ", " << EventAdd.Location.Z << ")" << std::endl; + // for (auto &Att : EventAdd.Description.Attributes) + // { + // Info << " " << TCHAR_TO_UTF8(*Att.Id) << " = " << TCHAR_TO_UTF8(*Att.Value) << std::endl; + // } + // UE_LOG(LogCarla, Log, TEXT("%s"), Info.str().c_str()); // auto Result = CallbackEventAdd( auto Result = Helper.ProcessReplayerEventAdd( @@ -331,10 +397,14 @@ void CarlaReplayer::ProcessEventsAdd(void) // actor created but with different id case 1: - if (Result.second != EventAdd.DatabaseId) - { - // UE_LOG(LogCarla, Log, TEXT("actor created but with different id")); - } + // if (Result.second != EventAdd.DatabaseId) + // { + // UE_LOG(LogCarla, Log, TEXT("actor created but with different id")); + // } + // else + // { + // UE_LOG(LogCarla, Log, TEXT("actor created with same id")); + // } // mapping id (recorded Id is a new Id in replayer) MappedId[EventAdd.DatabaseId] = Result.second; break; @@ -433,6 +503,8 @@ void CarlaReplayer::ProcessPositions(void) { Pos.DatabaseId = NewId->second; } + else + UE_LOG(LogCarla, Log, TEXT("Actor not found when trying to move from replayer (id. %d)"), Pos.DatabaseId); CurrPos.push_back(std::move(Pos)); } } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h index e286eb245..8329aa1b2 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h @@ -35,6 +35,18 @@ class CarlaReplayer #pragma pack(pop) public: + struct PlayAfterLoadMap + { + bool Enabled; + std::string Filename; + FString Mapfile; + double TimeStart; + double Duration; + uint32_t FollowId; + double TimeFactor; + }; + + static PlayAfterLoadMap Autoplay; CarlaReplayer() {}; ~CarlaReplayer() { Stop(); }; @@ -63,6 +75,9 @@ public: // playback speed (time factor) void SetSpeed(double NewTimeFactor); + // check if after a map is loaded, we need to replay + void CheckPlayAfterMapLoaded(void); + // tick for the replayer void Tick(float Time); From bac4060eb11c644f502dc97ce21b42c1d3f74730 Mon Sep 17 00:00:00 2001 From: bernatx Date: Mon, 11 Mar 2019 14:34:34 +0100 Subject: [PATCH 03/14] We can save in any folder now, or by default at 'Saved' folder. --- Docs/python_api_tutorial.md | 4 ++- .../Carla/Source/Carla/Game/CarlaEpisode.cpp | 3 +- .../Source/Carla/Recorder/CarlaRecorder.cpp | 28 +++++++++++-------- .../Source/Carla/Recorder/CarlaRecorder.h | 12 ++++---- .../Carla/Recorder/CarlaRecorderHelpers.cpp | 17 +++++++++++ .../Carla/Recorder/CarlaRecorderHelpers.h | 3 ++ .../Carla/Recorder/CarlaRecorderQuery.cpp | 21 ++++++++++---- .../Source/Carla/Recorder/CarlaReplayer.cpp | 11 +++++--- .../Source/Carla/Server/TheNewCarlaServer.cpp | 4 --- 9 files changed, 68 insertions(+), 35 deletions(-) diff --git a/Docs/python_api_tutorial.md b/Docs/python_api_tutorial.md index 37c12a852..c07255d6e 100644 --- a/Docs/python_api_tutorial.md +++ b/Docs/python_api_tutorial.md @@ -415,7 +415,9 @@ converted to OpenDrive format, and saved to disk as such. CARLA includes now a recording and replaying API, that allows to record a simulation in a file and later replay that simulation. The file is written on server side only, and it includes which **actors are created or destroyed** in the simulation, the **state of the traffic lights** and the **position/orientation** of all vehicles and walkers. -All data is written in a binary file on the server, on folder **CarlaUE4/Saved**. As estimation, a simulation with about 150 actors (50 traffic lights, 100 vehicles) for 1h of recording takes around 200 Mb in size. +All data is written in a binary file on the server. We can use filenames with or without a path. If we specify a filename without any of '\\', '/' or ':' characters, then it is considered to be only a filename and will be saved on folder **CarlaUE4/Saved**. If we use any of the previous characters then the filename will be considered as an absolute filename with path (for example: '/home/carla/recording01.log' or 'c:\\records\\recording01.log'). + +As estimation, a simulation with about 150 actors (50 traffic lights, 100 vehicles) for 1h of recording takes around 200 Mb in size. To start recording we only need to supply a file name: diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.cpp index 932d156d5..b68b79c40 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaEpisode.cpp @@ -221,11 +221,10 @@ void UCarlaEpisode::EndPlay(void) std::string UCarlaEpisode::StartRecorder(std::string Name) { std::string result; - FString Name2(Name.c_str()); if (Recorder) { - result = Recorder->Start(FPaths::ConvertRelativePathToFull(FPaths::ProjectSavedDir()), Name2, MapName); + result = Recorder->Start(Name, MapName); } else { diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp index fcfb557cc..95cdf259a 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp @@ -6,6 +6,7 @@ // #include "Carla.h" #include "CarlaRecorder.h" +#include "CarlaReplayerHelper.h" #include "Carla/Actor/ActorDescription.h" #include @@ -24,25 +25,25 @@ ACarlaRecorder::ACarlaRecorder(const FObjectInitializer &ObjectInitializer) Disable(); } -std::string ACarlaRecorder::ShowFileInfo(std::string Path, std::string Name) +std::string ACarlaRecorder::ShowFileInfo(std::string Name) { - return Query.QueryInfo(Path + Name); + return Query.QueryInfo(Name); } -std::string ACarlaRecorder::ShowFileCollisions(std::string Path, std::string Name, char Type1, char Type2) +std::string ACarlaRecorder::ShowFileCollisions(std::string Name, char Type1, char Type2) { - return Query.QueryCollisions(Path + Name, Type1, Type2); + return Query.QueryCollisions(Name, Type1, Type2); } -std::string ACarlaRecorder::ShowFileActorsBlocked(std::string Path, std::string Name, double MinTime, double MinDistance) +std::string ACarlaRecorder::ShowFileActorsBlocked(std::string Name, double MinTime, double MinDistance) { - return Query.QueryBlocked(Path + Name, MinTime, MinDistance); + return Query.QueryBlocked(Name, MinTime, MinDistance); } -std::string ACarlaRecorder::ReplayFile(std::string Path, std::string Name, double TimeStart, double Duration, uint32_t FollowId) +std::string ACarlaRecorder::ReplayFile(std::string Name, double TimeStart, double Duration, uint32_t FollowId) { Stop(); - return Replayer.ReplayFile(Path + Name, TimeStart, Duration, FollowId); + return Replayer.ReplayFile(Name, TimeStart, Duration, FollowId); } inline void ACarlaRecorder::SetReplayerSpeed(double TimeFactor) @@ -125,7 +126,7 @@ void ACarlaRecorder::Disable(void) Enabled = false; } -std::string ACarlaRecorder::Start(FString Path, FString Name, FString MapName) +std::string ACarlaRecorder::Start(std::string Name, FString MapName) { // stop replayer if any in course if (Replayer.IsEnabled()) @@ -134,13 +135,16 @@ std::string ACarlaRecorder::Start(FString Path, FString Name, FString MapName) // stop recording Stop(); + // reset collisions Id NextCollisionId = 0; - FString Filename = Path + Name; + + // get the final path + filename + std::string Filename = GetRecorderFilename(Name); // binary file // file.open(filename.str(), std::ios::binary | std::ios::trunc | // std::ios::out); - File.open(TCHAR_TO_UTF8(*Filename), std::ios::binary); + File.open(Filename, std::ios::binary); if (!File.is_open()) { return ""; @@ -162,7 +166,7 @@ std::string ACarlaRecorder::Start(FString Path, FString Name, FString MapName) // add all existing actors AddExistingActors(); - return std::string(TCHAR_TO_UTF8(*Filename)); + return std::string(Filename); } void ACarlaRecorder::Stop(void) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h index 9f77f933a..875f9925d 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h @@ -58,7 +58,7 @@ public: void Disable(void); // start / stop - std::string Start(FString Path, FString Name, FString MapName); + std::string Start(std::string Name, FString MapName); void Stop(void); @@ -98,11 +98,11 @@ public: return &Replayer; } - // forwarded to replayer - std::string ShowFileInfo(std::string Path, std::string Name); - std::string ShowFileCollisions(std::string Path, std::string Name, char Type1, char Type2); - std::string ShowFileActorsBlocked(std::string Path, std::string Name, double MinTime = 30, double MinDistance = 10); - std::string ReplayFile(std::string Path, std::string Name, double TimeStart, double Duration, uint32_t FollowId); + // queries + std::string ShowFileInfo(std::string Name); + std::string ShowFileCollisions(std::string Name, char Type1, char Type2); + std::string ShowFileActorsBlocked(std::string Name, double MinTime = 30, double MinDistance = 10); + std::string ReplayFile(std::string Name, double TimeStart, double Duration, uint32_t FollowId); void SetReplayerSpeed(double TimeFactor); void Tick(float DeltaSeconds) final; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderHelpers.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderHelpers.cpp index f073b54ca..21daff18b 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderHelpers.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderHelpers.cpp @@ -12,6 +12,23 @@ // create a temporal buffer to convert from and to FString and bytes static std::vector CarlaRecorderHelperBuffer; +// get the final path + filename +std::string GetRecorderFilename(std::string Filename) +{ + std::string Filename2; + + // check if a relative path was specified + if (Filename.find("\\") != std::string::npos || Filename.find("/") != std::string::npos || Filename.find(":") != std::string::npos) + Filename2 = Filename; + else + { + FString Path = FPaths::ConvertRelativePathToFull(FPaths::ProjectSavedDir()); + Filename2 = TCHAR_TO_UTF8(*Path) + Filename; + } + + return Filename2; +} + // ------ // write // ------ diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderHelpers.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderHelpers.h index b2118b51a..eb889c6f8 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderHelpers.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderHelpers.h @@ -8,6 +8,9 @@ #include +// get the final path + filename +std::string GetRecorderFilename(std::string Filename); + // --------- // recorder // --------- diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.cpp index 6b41becb9..68e1aa1b0 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.cpp @@ -54,11 +54,14 @@ std::string CarlaRecorderQuery::QueryInfo(std::string Filename, bool bShowAll) { std::stringstream Info; + // get the final path + filename + std::string Filename2 = GetRecorderFilename(Filename); + // try to open - File.open(Filename, std::ios::binary); + File.open(Filename2, std::ios::binary); if (!File.is_open()) { - Info << "File " << Filename << " not found on server\n"; + Info << "File " << Filename2 << " not found on server\n"; return Info.str(); } @@ -220,11 +223,14 @@ std::string CarlaRecorderQuery::QueryCollisions(std::string Filename, char Categ { std::stringstream Info; + // get the final path + filename + std::string Filename2 = GetRecorderFilename(Filename); + // try to open - File.open(Filename, std::ios::binary); + File.open(Filename2, std::ios::binary); if (!File.is_open()) { - Info << "File " << Filename << " not found on server\n"; + Info << "File " << Filename2 << " not found on server\n"; return Info.str(); } @@ -393,11 +399,14 @@ std::string CarlaRecorderQuery::QueryBlocked(std::string Filename, double MinTim { std::stringstream Info; + // get the final path + filename + std::string Filename2 = GetRecorderFilename(Filename); + // try to open - File.open(Filename, std::ios::binary); + File.open(Filename2, std::ios::binary); if (!File.is_open()) { - Info << "File " << Filename << " not found on server\n"; + Info << "File " << Filename2 << " not found on server\n"; return Info.str(); } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp index 3d26474c9..6fea48bd1 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp @@ -111,13 +111,16 @@ std::string CarlaReplayer::ReplayFile(std::string Filename, double TimeStart, do Stop(); } - Info << "Replaying File: " << Filename << std::endl; + // get the final path + filename + std::string Filename2 = GetRecorderFilename(Filename); + + Info << "Replaying File: " << Filename2 << std::endl; // try to open - File.open(Filename, std::ios::binary); + File.open(Filename2, std::ios::binary); if (!File.is_open()) { - Info << "File " << Filename << " not found on server\n"; + Info << "File " << Filename2 << " not found on server\n"; Stop(); return Info.str(); } @@ -139,7 +142,7 @@ std::string CarlaReplayer::ReplayFile(std::string Filename, double TimeStart, do // prepare autoplay after map is loaded Autoplay.Enabled = true; - Autoplay.Filename = Filename; + Autoplay.Filename = Filename2; Autoplay.Mapfile = RecInfo.Mapfile; Autoplay.TimeStart = TimeStart; Autoplay.Duration = Duration; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp index cdfa8c706..2c180368e 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp @@ -726,7 +726,6 @@ void FTheNewCarlaServer::FPimpl::BindActions() { REQUIRE_CARLA_EPISODE(); return R(Episode->GetRecorder()->ShowFileInfo( - carla::rpc::FromFString(FPaths::ConvertRelativePathToFull(FPaths::ProjectSavedDir())), name)); }; @@ -734,7 +733,6 @@ void FTheNewCarlaServer::FPimpl::BindActions() { REQUIRE_CARLA_EPISODE(); return R(Episode->GetRecorder()->ShowFileCollisions( - carla::rpc::FromFString(FPaths::ConvertRelativePathToFull(FPaths::ProjectSavedDir())), name, type1, type2)); @@ -744,7 +742,6 @@ void FTheNewCarlaServer::FPimpl::BindActions() { REQUIRE_CARLA_EPISODE(); return R(Episode->GetRecorder()->ShowFileActorsBlocked( - carla::rpc::FromFString(FPaths::ConvertRelativePathToFull(FPaths::ProjectSavedDir())), name, min_time, min_distance)); @@ -754,7 +751,6 @@ void FTheNewCarlaServer::FPimpl::BindActions() { REQUIRE_CARLA_EPISODE(); return R(Episode->GetRecorder()->ReplayFile( - carla::rpc::FromFString(FPaths::ConvertRelativePathToFull(FPaths::ProjectSavedDir())), name, start, duration, From d9975dfde948b1287c642d43c4f457900cdae7c7 Mon Sep 17 00:00:00 2001 From: bernatx Date: Tue, 12 Mar 2019 14:34:54 +0100 Subject: [PATCH 04/14] Fixed a bug where using a reference of a local variable --- .../Source/Carla/Recorder/CarlaReplayerHelper.cpp | 14 +++++++------- .../Source/Carla/Recorder/CarlaReplayerHelper.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp index 00b1ac5c2..757b0babc 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.cpp @@ -9,7 +9,7 @@ #include "Carla/Actor/ActorDescription.h" // create or reuse an actor for replaying -std::pairCarlaReplayerHelper::TryToCreateReplayerActor( +std::pairCarlaReplayerHelper::TryToCreateReplayerActor( FVector &Location, FVector &Rotation, FActorDescription &ActorDesc, @@ -29,13 +29,13 @@ std::pairCarlaReplayerHelper::TryToCreateReplayerActor( auto view = Episode->GetActorRegistry().Find(Actor); // reuse that actor // UE_LOG(LogCarla, Log, TEXT("TrafficLight found with id: %d"), view.GetActorId()); - return std::pair(2, view); + return std::pair(2, view); } else { // actor not found UE_LOG(LogCarla, Log, TEXT("TrafficLight not found")); - return std::pair(0, view_empty); + return std::pair(0, view_empty); } } else if (!ActorDesc.Id.StartsWith("sensor.")) @@ -50,7 +50,7 @@ std::pairCarlaReplayerHelper::TryToCreateReplayerActor( if (desc->Id == ActorDesc.Id) { // we don't need to create, actor of same type already exist - return std::pair(2, view); + return std::pair(2, view); } } // create the transform @@ -66,18 +66,18 @@ std::pairCarlaReplayerHelper::TryToCreateReplayerActor( FTransform Trans2(Rot, Location, FVector(1, 1, 1)); Result.Value.GetActor()->SetActorTransform(Trans2, false, nullptr, ETeleportType::TeleportPhysics); // Result.Value.GetActor()->SetLocation(Trans2); - return std::pair(1, Result.Value); + return std::pair(1, Result.Value); } else { UE_LOG(LogCarla, Log, TEXT("Actor could't be created by replayer")); - return std::pair(0, Result.Value); + return std::pair(0, Result.Value); } } else { // actor ignored - return std::pair(0, view_empty); + return std::pair(0, view_empty); } } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.h index ad18b9ebe..c2ec2a86e 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayerHelper.h @@ -50,7 +50,7 @@ private: UCarlaEpisode *Episode {nullptr}; - std::pairTryToCreateReplayerActor( + std::pairTryToCreateReplayerActor( FVector &Location, FVector &Rotation, FActorDescription &ActorDesc, From 708f0c662382f9b5670c9a5e633455e1310467b1 Mon Sep 17 00:00:00 2001 From: bernatx Date: Thu, 14 Mar 2019 14:50:22 +0100 Subject: [PATCH 05/14] Fix return of void function --- .../Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp index 95cdf259a..f7de7e675 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp @@ -48,7 +48,7 @@ std::string ACarlaRecorder::ReplayFile(std::string Name, double TimeStart, doubl inline void ACarlaRecorder::SetReplayerSpeed(double TimeFactor) { - return Replayer.SetSpeed(TimeFactor); + Replayer.SetSpeed(TimeFactor); } void ACarlaRecorder::Tick(float DeltaSeconds) From c6ff4cb3620d23df29891b3cb00d511107af6d32 Mon Sep 17 00:00:00 2001 From: bernatx Date: Thu, 28 Mar 2019 11:48:14 +0100 Subject: [PATCH 06/14] Added an optional parameter to show more details about a recorder file Related to the show_recorder_file_info.py API --- CHANGELOG.md | 1 + LibCarla/source/carla/client/Client.h | 4 +-- .../source/carla/client/detail/Client.cpp | 4 +-- LibCarla/source/carla/client/detail/Client.h | 2 +- .../source/carla/client/detail/Simulator.h | 4 +-- PythonAPI/carla/source/libcarla/Client.cpp | 2 +- PythonAPI/examples/show_recorder_file_info.py | 6 ++++- .../Source/Carla/Recorder/CarlaRecorder.cpp | 4 +-- .../Source/Carla/Recorder/CarlaRecorder.h | 2 +- .../Carla/Recorder/CarlaRecorderQuery.cpp | 27 ++++++++++++++++--- .../Source/Carla/Server/TheNewCarlaServer.cpp | 5 ++-- 11 files changed, 44 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22a7daa45..3b75adac2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## CARLA 0.9.5 + * Added optional parameter to show more details about a recorder file (related to `show_recorder_file_info.py`) * Added playback speed (slow/fast motion) for the replayer * We can use an absolute path for the recorded files (to choose where to 'write to' or 'read from') * New Town07, rural environment with narrow roads diff --git a/LibCarla/source/carla/client/Client.h b/LibCarla/source/carla/client/Client.h index e4a169329..c11b55e5f 100644 --- a/LibCarla/source/carla/client/Client.h +++ b/LibCarla/source/carla/client/Client.h @@ -68,8 +68,8 @@ namespace client { _simulator->StopRecorder(); } - std::string ShowRecorderFileInfo(std::string name) { - return _simulator->ShowRecorderFileInfo(name); + std::string ShowRecorderFileInfo(std::string name, bool show_all) { + return _simulator->ShowRecorderFileInfo(name, show_all); } std::string ShowRecorderCollisions(std::string name, char type1, char type2) { diff --git a/LibCarla/source/carla/client/detail/Client.cpp b/LibCarla/source/carla/client/detail/Client.cpp index 70dc07703..daedc0b99 100644 --- a/LibCarla/source/carla/client/detail/Client.cpp +++ b/LibCarla/source/carla/client/detail/Client.cpp @@ -275,8 +275,8 @@ namespace detail { return _pimpl->AsyncCall("stop_recorder"); } - std::string Client::ShowRecorderFileInfo(std::string name) { - return _pimpl->CallAndWait("show_recorder_file_info", name); + std::string Client::ShowRecorderFileInfo(std::string name, bool show_all) { + return _pimpl->CallAndWait("show_recorder_file_info", name, show_all); } std::string Client::ShowRecorderCollisions(std::string name, char type1, char type2) { diff --git a/LibCarla/source/carla/client/detail/Client.h b/LibCarla/source/carla/client/detail/Client.h index eca24ee47..4a25196ca 100644 --- a/LibCarla/source/carla/client/detail/Client.h +++ b/LibCarla/source/carla/client/detail/Client.h @@ -174,7 +174,7 @@ namespace detail { void StopRecorder(); - std::string ShowRecorderFileInfo(std::string name); + std::string ShowRecorderFileInfo(std::string name, bool show_all); std::string ShowRecorderCollisions(std::string name, char type1, char type2); diff --git a/LibCarla/source/carla/client/detail/Simulator.h b/LibCarla/source/carla/client/detail/Simulator.h index b3b9c3bde..9b1a8ff70 100644 --- a/LibCarla/source/carla/client/detail/Simulator.h +++ b/LibCarla/source/carla/client/detail/Simulator.h @@ -277,8 +277,8 @@ namespace detail { _client.StopRecorder(); } - std::string ShowRecorderFileInfo(std::string name) { - return _client.ShowRecorderFileInfo(std::move(name)); + std::string ShowRecorderFileInfo(std::string name, bool show_all) { + return _client.ShowRecorderFileInfo(std::move(name), show_all); } std::string ShowRecorderCollisions(std::string name, char type1, char type2) { diff --git a/PythonAPI/carla/source/libcarla/Client.cpp b/PythonAPI/carla/source/libcarla/Client.cpp index 4b51f5f20..7b0e3d9a0 100644 --- a/PythonAPI/carla/source/libcarla/Client.cpp +++ b/PythonAPI/carla/source/libcarla/Client.cpp @@ -64,7 +64,7 @@ void export_client() { .def("load_world", CONST_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"))) + .def("show_recorder_file_info", CALL_WITHOUT_GIL_2(cc::Client, ShowRecorderFileInfo, std::string, bool), (arg("name"), arg("show_all"))) .def("show_recorder_collisions", CALL_WITHOUT_GIL_3(cc::Client, ShowRecorderCollisions, std::string, char, char), (arg("name"), arg("type1"), arg("type2"))) .def("show_recorder_actors_blocked", CALL_WITHOUT_GIL_3(cc::Client, ShowRecorderActorsBlocked, std::string, float, float), (arg("name"), arg("min_time"), arg("min_distance"))) .def("replay_file", CALL_WITHOUT_GIL_4(cc::Client, ReplayFile, std::string, float, float, int), (arg("name"), arg("time_start"), arg("duration"), arg("follow_id"))) diff --git a/PythonAPI/examples/show_recorder_file_info.py b/PythonAPI/examples/show_recorder_file_info.py index ad832df8d..f9f5f45aa 100755 --- a/PythonAPI/examples/show_recorder_file_info.py +++ b/PythonAPI/examples/show_recorder_file_info.py @@ -43,6 +43,10 @@ def main(): metavar='F', default="test1.rec", help='recorder filename (test1.rec)') + argparser.add_argument( + '-a', '--show_all', + action='store_true', + help='show detailed info about all frames content') args = argparser.parse_args() try: @@ -50,7 +54,7 @@ def main(): client = carla.Client(args.host, args.port) client.set_timeout(60.0) - print(client.show_recorder_file_info(args.recorder_filename)) + print(client.show_recorder_file_info(args.recorder_filename, args.show_all)) finally: pass diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp index f7de7e675..f1c59f142 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp @@ -25,9 +25,9 @@ ACarlaRecorder::ACarlaRecorder(const FObjectInitializer &ObjectInitializer) Disable(); } -std::string ACarlaRecorder::ShowFileInfo(std::string Name) +std::string ACarlaRecorder::ShowFileInfo(std::string Name, bool bShowAll) { - return Query.QueryInfo(Name); + return Query.QueryInfo(Name, bShowAll); } std::string ACarlaRecorder::ShowFileCollisions(std::string Name, char Type1, char Type2) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h index 875f9925d..70042d76c 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h @@ -99,7 +99,7 @@ public: } // queries - std::string ShowFileInfo(std::string Name); + std::string ShowFileInfo(std::string Name, bool bShowAll = false); std::string ShowFileCollisions(std::string Name, char Type1, char Type2); std::string ShowFileActorsBlocked(std::string Name, double MinTime = 30, double MinDistance = 10); std::string ReplayFile(std::string Name, double TimeStart, double Duration, uint32_t FollowId); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.cpp index 68e1aa1b0..098ff8cec 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorderQuery.cpp @@ -94,7 +94,13 @@ std::string CarlaRecorderQuery::QueryInfo(std::string Filename, bool bShowAll) // frame case static_cast(CarlaRecorderPacketId::FrameStart): Frame.Read(File); - bFramePrinted = false; + if (bShowAll) + { + PrintFrame(Info); + bFramePrinted = true; + } + else + bFramePrinted = false; break; // events add @@ -173,8 +179,23 @@ std::string CarlaRecorderQuery::QueryInfo(std::string Filename, bool bShowAll) break; case static_cast(CarlaRecorderPacketId::Position): - // Info << "Positions\n"; - SkipPacket(); + if (bShowAll) + { + ReadValue(File, Total); + if (Total > 0 && !bFramePrinted) + { + PrintFrame(Info); + bFramePrinted = true; + } + Info << " Positions: " << Total << std::endl; + for (i = 0; i < Total; ++i) + { + Position.Read(File); + Info << " Id: " << Position.DatabaseId << " Location (" << Position.Location.X << ", " << Position.Location.Y << ", " << Position.Location.Z << ") Rotation (" << Position.Rotation.X << ", " << Position.Rotation.Y << ", " << Position.Rotation.Z << ")" << std::endl; + } + } + else + SkipPacket(); break; case static_cast(CarlaRecorderPacketId::State): diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp index 2c180368e..b9d078025 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp @@ -722,11 +722,12 @@ void FTheNewCarlaServer::FPimpl::BindActions() return R::Success(); }; - BIND_SYNC(show_recorder_file_info) << [this](std::string name) -> R + BIND_SYNC(show_recorder_file_info) << [this](std::string name, bool show_all) -> R { REQUIRE_CARLA_EPISODE(); return R(Episode->GetRecorder()->ShowFileInfo( - name)); + name, + show_all)); }; BIND_SYNC(show_recorder_collisions) << [this](std::string name, char type1, char type2) -> R From 6d7b3d00ef8d95b63b6e724bce34a8043ada86d7 Mon Sep 17 00:00:00 2001 From: bernatx Date: Thu, 4 Apr 2019 11:32:22 +0200 Subject: [PATCH 07/14] Fixing PyLint warnings --- PythonAPI/set_replayer_speed.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/PythonAPI/set_replayer_speed.py b/PythonAPI/set_replayer_speed.py index 53f465a3c..b51924201 100644 --- a/PythonAPI/set_replayer_speed.py +++ b/PythonAPI/set_replayer_speed.py @@ -9,6 +9,7 @@ import glob import os import sys +import argparse try: sys.path.append(glob.glob('**/*%d.%d-%s.egg' % ( @@ -20,9 +21,6 @@ except IndexError: import carla -import argparse -import random -import time def main(): From c2b7e27ac5d254eac0071e90067a6a1689ea206a Mon Sep 17 00:00:00 2001 From: bernatx Date: Thu, 11 Apr 2019 11:38:19 +0200 Subject: [PATCH 08/14] Updated CHANGE.LOG and telling playback speed when replaying --- CHANGELOG.md | 7 ++++--- .../Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b75adac2..fdde4c37a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ ## CARLA 0.9.5 - * Added optional parameter to show more details about a recorder file (related to `show_recorder_file_info.py`) - * Added playback speed (slow/fast motion) for the replayer - * We can use an absolute path for the recorded files (to choose where to 'write to' or 'read from') + * New recorder features: + - Added optional parameter to show more details about a recorder file (related to `show_recorder_file_info.py`) + - Added playback speed (slow/fast motion) for the replayer + - We can use an absolute path for the recorded files (to choose where to 'write to' or 'read from') * New Town07, rural environment with narrow roads * Reworked OpenDRIVE parser and waypoints API - Fixed several situations in which the XODR was incorrectly parsed diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp index 6fea48bd1..99c249bf3 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp @@ -168,8 +168,8 @@ std::string CarlaReplayer::ReplayFile(std::string Filename, double TimeStart, do else TimeToStop = TotalTime; - Info << "Replaying from " << TimeStart << " s - " << TimeToStop << " s (" << TotalTime << " s)" << - std::endl; + Info << "Replaying from " << TimeStart << " s - " << TimeToStop << " s (" << TotalTime << " s) at " << + std::setprecision(1) << std::fixed << TimeFactor << "x" << std::endl; // set the follow Id FollowId = ThisFollowId; From 2d2f1654dc8317adea9b748d1663c811b3f6f9ba Mon Sep 17 00:00:00 2001 From: bernatx Date: Thu, 11 Apr 2019 15:00:12 +0200 Subject: [PATCH 09/14] Use batch commands to create and remove actors from recorder --- PythonAPI/examples/start_recording.py | 72 +++++++++++++++------------ 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/PythonAPI/examples/start_recording.py b/PythonAPI/examples/start_recording.py index 23a60ba05..35f48c058 100755 --- a/PythonAPI/examples/start_recording.py +++ b/PythonAPI/examples/start_recording.py @@ -23,6 +23,7 @@ import carla import argparse import random import time +import logging def main(): @@ -69,6 +70,7 @@ def main(): args = argparser.parse_args() actor_list = [] + logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO) try: @@ -77,24 +79,6 @@ def main(): world = client.get_world() blueprints = world.get_blueprint_library().filter('vehicle.*') - if args.safe: - blueprints = [x for x in blueprints if int(x.get_attribute('number_of_wheels')) == 4] - blueprints = [x for x in blueprints if not x.id.endswith('isetta')] - - def try_spawn_random_vehicle_at(transform): - blueprint = random.choice(blueprints) - if blueprint.has_attribute('color'): - color = random.choice(blueprint.get_attribute('color').recommended_values) - blueprint.set_attribute('color', color) - blueprint.set_attribute('role_name', 'autopilot') - vehicle = world.try_spawn_actor(blueprint, transform) - if vehicle is not None: - actor_list.append(vehicle) - vehicle.set_autopilot() - print('spawned %r at %s' % (vehicle.type_id, transform.location)) - return True - return False - # @todo Needs to be converted to list to be shuffled. spawn_points = list(world.get_map().get_spawn_points()) random.shuffle(spawn_points) @@ -103,32 +87,58 @@ def main(): count = args.number_of_vehicles - print("Recording on file:", client.start_recorder(args.recorder_filename)) + print("Recording on file: %s" % client.start_recorder(args.recorder_filename)) - for spawn_point in spawn_points: - if try_spawn_random_vehicle_at(spawn_point): - count -= 1 - if count <= 0: + if args.safe: + blueprints = [x for x in blueprints if int(x.get_attribute('number_of_wheels')) == 4] + blueprints = [x for x in blueprints if not x.id.endswith('isetta')] + blueprints = [x for x in blueprints if not x.id.endswith('carlacola')] + + spawn_points = world.get_map().get_spawn_points() + number_of_spawn_points = len(spawn_points) + + if args.number_of_vehicles < number_of_spawn_points: + random.shuffle(spawn_points) + elif args.number_of_vehicles > number_of_spawn_points: + msg = 'requested %d vehicles, but could only find %d spawn points' + logging.warning(msg, args.number_of_vehicles, number_of_spawn_points) + args.number_of_vehicles = number_of_spawn_points + + # @todo cannot import these directly. + SpawnActor = carla.command.SpawnActor + SetAutopilot = carla.command.SetAutopilot + FutureActor = carla.command.FutureActor + + batch = [] + for n, transform in enumerate(spawn_points): + if n >= args.number_of_vehicles: break + blueprint = random.choice(blueprints) + if blueprint.has_attribute('color'): + color = random.choice(blueprint.get_attribute('color').recommended_values) + blueprint.set_attribute('color', color) + blueprint.set_attribute('role_name', 'autopilot') + batch.append(SpawnActor(blueprint, transform).then(SetAutopilot(FutureActor, True))) - while count > 0: - time.sleep(args.delay) - if try_spawn_random_vehicle_at(random.choice(spawn_points)): - count -= 1 + for response in client.apply_batch_sync(batch): + if response.error: + logging.error(response.error) + else: + actor_list.append(response.actor_id) - print('spawned %d vehicles, press Ctrl+C to exit.' % args.number_of_vehicles) + print('spawned %d vehicles, press Ctrl+C to exit.' % len(actor_list)) if (args.recorder_time > 0): time.sleep(args.recorder_time) else: while True: - time.sleep(0.1) + world.wait_for_tick() + # time.sleep(0.1) finally: print('\ndestroying %d actors' % len(actor_list)) - for actor in actor_list: - actor.destroy() + client.apply_batch([carla.command.DestroyActor(x) for x in actor_list]) print("Stop recording") client.stop_recorder() From 739142954d5de2a7766480b111763b5ff41421d5 Mon Sep 17 00:00:00 2001 From: bernatx Date: Thu, 11 Apr 2019 16:01:12 +0200 Subject: [PATCH 10/14] Renaming playback speed by playback time factor --- LibCarla/source/carla/client/Client.h | 4 ++-- LibCarla/source/carla/client/detail/Client.cpp | 4 ++-- LibCarla/source/carla/client/detail/Client.h | 2 +- LibCarla/source/carla/client/detail/Simulator.h | 4 ++-- PythonAPI/carla/source/libcarla/Client.cpp | 2 +- PythonAPI/examples/start_replaying.py | 6 +++--- .../Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp | 4 ++-- .../Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h | 2 +- .../Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp | 6 ------ .../Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h | 5 ++++- .../Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp | 4 ++-- 11 files changed, 20 insertions(+), 23 deletions(-) diff --git a/LibCarla/source/carla/client/Client.h b/LibCarla/source/carla/client/Client.h index c11b55e5f..e09c0cbdd 100644 --- a/LibCarla/source/carla/client/Client.h +++ b/LibCarla/source/carla/client/Client.h @@ -84,8 +84,8 @@ namespace client { return _simulator->ReplayFile(name, start, duration, follow_id); } - void SetReplayerSpeed(double time_factor) { - _simulator->SetReplayerSpeed(time_factor); + void SetReplayerTimeFactor(double time_factor) { + _simulator->SetReplayerTimeFactor(time_factor); } void ApplyBatch( diff --git a/LibCarla/source/carla/client/detail/Client.cpp b/LibCarla/source/carla/client/detail/Client.cpp index daedc0b99..e5e660db2 100644 --- a/LibCarla/source/carla/client/detail/Client.cpp +++ b/LibCarla/source/carla/client/detail/Client.cpp @@ -291,8 +291,8 @@ namespace detail { return _pimpl->CallAndWait("replay_file", name, start, duration, follow_id); } - void Client::SetReplayerSpeed(double time_factor) { - _pimpl->AsyncCall("set_replayer_speed", time_factor); + void Client::SetReplayerTimeFactor(double time_factor) { + _pimpl->AsyncCall("set_replayer_time_factor", time_factor); } void Client::SubscribeToStream( diff --git a/LibCarla/source/carla/client/detail/Client.h b/LibCarla/source/carla/client/detail/Client.h index 4a25196ca..5454f5b86 100644 --- a/LibCarla/source/carla/client/detail/Client.h +++ b/LibCarla/source/carla/client/detail/Client.h @@ -182,7 +182,7 @@ namespace detail { std::string ReplayFile(std::string name, double start, double duration, uint32_t follow_id); - void SetReplayerSpeed(double time_factor); + void SetReplayerTimeFactor(double time_factor); void SubscribeToStream( const streaming::Token &token, diff --git a/LibCarla/source/carla/client/detail/Simulator.h b/LibCarla/source/carla/client/detail/Simulator.h index 9b1a8ff70..91730d52f 100644 --- a/LibCarla/source/carla/client/detail/Simulator.h +++ b/LibCarla/source/carla/client/detail/Simulator.h @@ -293,8 +293,8 @@ namespace detail { return _client.ReplayFile(std::move(name), start, duration, follow_id); } - void SetReplayerSpeed(double time_factor) { - _client.SetReplayerSpeed(time_factor); + void SetReplayerTimeFactor(double time_factor) { + _client.SetReplayerTimeFactor(time_factor); } /// @} diff --git a/PythonAPI/carla/source/libcarla/Client.cpp b/PythonAPI/carla/source/libcarla/Client.cpp index 7b0e3d9a0..5514377e5 100644 --- a/PythonAPI/carla/source/libcarla/Client.cpp +++ b/PythonAPI/carla/source/libcarla/Client.cpp @@ -68,7 +68,7 @@ void export_client() { .def("show_recorder_collisions", CALL_WITHOUT_GIL_3(cc::Client, ShowRecorderCollisions, std::string, char, char), (arg("name"), arg("type1"), arg("type2"))) .def("show_recorder_actors_blocked", CALL_WITHOUT_GIL_3(cc::Client, ShowRecorderActorsBlocked, std::string, float, float), (arg("name"), arg("min_time"), arg("min_distance"))) .def("replay_file", CALL_WITHOUT_GIL_4(cc::Client, ReplayFile, std::string, float, float, int), (arg("name"), arg("time_start"), arg("duration"), arg("follow_id"))) - .def("set_replayer_speed", &cc::Client::SetReplayerSpeed, (arg("time_factor"))) + .def("set_replayer_time_factor", &cc::Client::SetReplayerTimeFactor, (arg("time_factor"))) .def("apply_batch", &ApplyBatchCommands, (arg("commands"), arg("do_tick")=false)) .def("apply_batch_sync", &ApplyBatchCommandsSync, (arg("commands"), arg("do_tick")=false)) ; diff --git a/PythonAPI/examples/start_replaying.py b/PythonAPI/examples/start_replaying.py index 75adc3a23..aee42975b 100755 --- a/PythonAPI/examples/start_replaying.py +++ b/PythonAPI/examples/start_replaying.py @@ -62,11 +62,11 @@ def main(): type=int, help='camera follows an actor (ex: 82)') argparser.add_argument( - '-x', '--speed', + '-x', '--time_factor', metavar='X', default=1.0, type=float, - help='time factor(default 1.0)') + help='time factor (default 1.0)') args = argparser.parse_args() try: @@ -74,7 +74,7 @@ def main(): client = carla.Client(args.host, args.port) client.set_timeout(60.0) - client.set_replayer_speed(args.speed) + client.set_replayer_time_factor(args.time_factor) print(client.replay_file(args.recorder_filename, args.start, args.duration, args.camera)) finally: diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp index f1c59f142..08a3a2a06 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.cpp @@ -46,9 +46,9 @@ std::string ACarlaRecorder::ReplayFile(std::string Name, double TimeStart, doubl return Replayer.ReplayFile(Name, TimeStart, Duration, FollowId); } -inline void ACarlaRecorder::SetReplayerSpeed(double TimeFactor) +inline void ACarlaRecorder::SetReplayerTimeFactor(double TimeFactor) { - Replayer.SetSpeed(TimeFactor); + Replayer.SetTimeFactor(TimeFactor); } void ACarlaRecorder::Tick(float DeltaSeconds) diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h index 70042d76c..af06a8aab 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaRecorder.h @@ -103,7 +103,7 @@ public: std::string ShowFileCollisions(std::string Name, char Type1, char Type2); std::string ShowFileActorsBlocked(std::string Name, double MinTime = 30, double MinDistance = 10); std::string ReplayFile(std::string Name, double TimeStart, double Duration, uint32_t FollowId); - void SetReplayerSpeed(double TimeFactor); + void SetReplayerTimeFactor(double TimeFactor); void Tick(float DeltaSeconds) final; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp index 99c249bf3..44030db73 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.cpp @@ -587,9 +587,3 @@ void CarlaReplayer::Tick(float Delta) // UE_LOG(LogCarla, Log, TEXT("Replayer tick")); } - -// speed (time factor) -inline void CarlaReplayer::SetSpeed(double NewTimeFactor) -{ - TimeFactor = NewTimeFactor; -} \ No newline at end of file diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h index 8329aa1b2..4baf268a4 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Recorder/CarlaReplayer.h @@ -73,7 +73,10 @@ public: } // playback speed (time factor) - void SetSpeed(double NewTimeFactor); + void SetTimeFactor(double NewTimeFactor) + { + TimeFactor = NewTimeFactor; + } // check if after a map is loaded, we need to replay void CheckPlayAfterMapLoaded(void); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp index b9d078025..7590c5aba 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Server/TheNewCarlaServer.cpp @@ -758,10 +758,10 @@ void FTheNewCarlaServer::FPimpl::BindActions() follow_id)); }; - BIND_SYNC(set_replayer_speed) << [this](double time_factor) -> R + BIND_SYNC(set_replayer_time_factor) << [this](double time_factor) -> R { REQUIRE_CARLA_EPISODE(); - Episode->GetRecorder()->SetReplayerSpeed(time_factor); + Episode->GetRecorder()->SetReplayerTimeFactor(time_factor); return R::Success(); }; From 78ef040485b7b5663acf893e2e2cd05c5cd441d3 Mon Sep 17 00:00:00 2001 From: bernatx Date: Thu, 11 Apr 2019 16:16:58 +0200 Subject: [PATCH 11/14] Removed script to change playback time factor (no needed) --- PythonAPI/set_replayer_speed.py | 68 --------------------------------- 1 file changed, 68 deletions(-) delete mode 100644 PythonAPI/set_replayer_speed.py diff --git a/PythonAPI/set_replayer_speed.py b/PythonAPI/set_replayer_speed.py deleted file mode 100644 index b51924201..000000000 --- a/PythonAPI/set_replayer_speed.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python - -# 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 . - -import glob -import os -import sys -import argparse - -try: - sys.path.append(glob.glob('**/*%d.%d-%s.egg' % ( - sys.version_info.major, - sys.version_info.minor, - 'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0]) -except IndexError: - pass - -import carla - - - -def main(): - - argparser = argparse.ArgumentParser( - description=__doc__) - argparser.add_argument( - '--host', - metavar='H', - default='127.0.0.1', - help='IP of the host server (default: 127.0.0.1)') - argparser.add_argument( - '-p', '--port', - metavar='P', - default=2000, - type=int, - help='TCP port to listen to (default: 2000)') - argparser.add_argument( - '-x', '--speed', - metavar='X', - default=1.0, - type=float, - help='time factor(default 1.0)') - args = argparser.parse_args() - - try: - - client = carla.Client(args.host, args.port) - client.set_timeout(2.0) - - # client.load_world("Town03") - - client.set_replayer_speed(args.speed) - - finally: - pass - -if __name__ == '__main__': - - try: - main() - except KeyboardInterrupt: - pass - finally: - print('\ndone.') From af6796b16e3bae574baeb9d472b7023dc7df85a5 Mon Sep 17 00:00:00 2001 From: bernatx Date: Thu, 11 Apr 2019 17:47:59 +0200 Subject: [PATCH 12/14] Fixing script with pyLint --- PythonAPI/examples/start_recording.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/PythonAPI/examples/start_recording.py b/PythonAPI/examples/start_recording.py index 35f48c058..ba3afba42 100755 --- a/PythonAPI/examples/start_recording.py +++ b/PythonAPI/examples/start_recording.py @@ -97,12 +97,12 @@ def main(): spawn_points = world.get_map().get_spawn_points() number_of_spawn_points = len(spawn_points) - if args.number_of_vehicles < number_of_spawn_points: + if count < number_of_spawn_points: random.shuffle(spawn_points) - elif args.number_of_vehicles > number_of_spawn_points: + elif count > number_of_spawn_points: msg = 'requested %d vehicles, but could only find %d spawn points' - logging.warning(msg, args.number_of_vehicles, number_of_spawn_points) - args.number_of_vehicles = number_of_spawn_points + logging.warning(msg, count, number_of_spawn_points) + count = number_of_spawn_points # @todo cannot import these directly. SpawnActor = carla.command.SpawnActor @@ -111,7 +111,7 @@ def main(): batch = [] for n, transform in enumerate(spawn_points): - if n >= args.number_of_vehicles: + if n >= count: break blueprint = random.choice(blueprints) if blueprint.has_attribute('color'): From 53dab06035e351fc33dee5d48acfbc82bf28254e Mon Sep 17 00:00:00 2001 From: bernatx Date: Fri, 12 Apr 2019 11:49:58 +0200 Subject: [PATCH 13/14] Updated the documentation --- Docs/python_api_tutorial.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Docs/python_api_tutorial.md b/Docs/python_api_tutorial.md index c07255d6e..e466f85d2 100644 --- a/Docs/python_api_tutorial.md +++ b/Docs/python_api_tutorial.md @@ -451,10 +451,10 @@ client.replay_file("recording01.log", start, duration, camera) * **duration**: we can say how many seconds we want to play. If the simulation has not reached the end, then all actors will have autopilot enabled automatically. The intention here is to allow for replaying a piece of a simulation and then let all actors start driving in autopilot again. * **camera**: we can specify the Id of an actor and then the camera will follow that actor while replaying. Continue reading to know which Id has an actor. -We can specify the speed for the replayer at any moment, using the next API: +We can specify the time factor (speed) for the replayer at any moment, using the next API: ```py -client.set_replayer_speed(2.0) +client.set_replayer_time_factor(2.0) ``` A value greater than 1.0 will play in fast motion, and a value below 1.0 will play in slow motion, being 1.0 the default value for normal playback. As a performance trick, with values over 2.0 the interpolation of positions is disabled. From 1910095ad1694d79f54a9c6d83141fa849e5dcdc Mon Sep 17 00:00:00 2001 From: bernatx Date: Fri, 12 Apr 2019 18:29:40 +0200 Subject: [PATCH 14/14] Updating CHANGELOG.MD --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdde4c37a..4629832ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,12 @@ -## CARLA 0.9.5 +## Latest * New recorder features: - Added optional parameter to show more details about a recorder file (related to `show_recorder_file_info.py`) - Added playback speed (slow/fast motion) for the replayer - We can use an absolute path for the recorded files (to choose where to 'write to' or 'read from') + +## CARLA 0.9.5 + * New Town07, rural environment with narrow roads * Reworked OpenDRIVE parser and waypoints API - Fixed several situations in which the XODR was incorrectly parsed