Added replayer speed (time factor for slow/fast motion)
This commit is contained in:
parent
4ec09d262e
commit
be37d22335
|
@ -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
|
||||
|
|
|
@ -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)`
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<rpc::Command> commands,
|
||||
bool do_tick_cue = false) const {
|
||||
|
|
|
@ -291,6 +291,10 @@ namespace detail {
|
|||
return _pimpl->CallAndWait<std::string>("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<void(Buffer)> callback) {
|
||||
|
|
|
@ -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<void(Buffer)> callback);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 <https://opensource.org/licenses/MIT>.
|
||||
|
||||
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.')
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -761,6 +761,13 @@ void FTheNewCarlaServer::FPimpl::BindActions()
|
|||
follow_id));
|
||||
};
|
||||
|
||||
BIND_SYNC(set_replayer_speed) << [this](double time_factor) -> R<void>
|
||||
{
|
||||
REQUIRE_CARLA_EPISODE();
|
||||
Episode->GetRecorder()->SetReplayerSpeed(time_factor);
|
||||
return R<void>::Success();
|
||||
};
|
||||
|
||||
// ~~ Draw debug shapes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
BIND_SYNC(draw_debug_shape) << [this](const cr::DebugShape &shape) -> R<void>
|
||||
|
|
Loading…
Reference in New Issue