CARLA
 
载入中...
搜索中...
未找到
CarlaReplayer.cpp
浏览该文件的文档.
1// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#include "CarlaReplayer.h"
8#include "CarlaRecorder.h"
10
11#include <ctime>
12#include <sstream>
13
14// structure to save replaying info when need to load a new map (static member by now)
15CarlaReplayer::PlayAfterLoadMap CarlaReplayer::Autoplay { false, "", "", 0.0, 0.0, 0, 1.0, false };
16
17void CarlaReplayer::Stop(bool bKeepActors)
18{
19 if (Enabled)
20 {
21 Enabled = false;
22
23 // destroy actors if event was recorded?
24 if (!bKeepActors)
25 {
27 }
28
29 // callback
31 }
32
33 if (File.is_open())
34 File.close();
35}
36
38{
39 if (File.eof())
40 {
41 return false;
42 }
43
44 ReadValue<char>(File, Header.Id);
45 ReadValue<uint32_t>(File, Header.Size);
46
47 return true;
48}
49
51{
52 File.seekg(Header.Size, std::ios::cur);
53}
54
56{
57 CurrentTime = 0.0f;
58 TotalTime = 0.0f;
59 TimeToStop = 0.0f;
60
61 File.clear();
62 File.seekg(0, std::ios::beg);
63
64 // mark as header as invalid to force reload a new one next time
65 Frame.Elapsed = -1.0f;
66 Frame.DurationThis = 0.0f;
67
68 MappedId.clear();
69 IsHeroMap.clear();
70
71 // read geneal Info
73}
74
75// read last frame in File and return the Total time recorded
77{
78 std::streampos Current = File.tellg();
79
80 // parse only frames
81 while (File)
82 {
83 // get header
84 if (!ReadHeader())
85 {
86 break;
87 }
88
89 // check for a frame packet
90 switch (Header.Id)
91 {
92 case static_cast<char>(CarlaRecorderPacketId::FrameStart):
94 break;
95 default:
96 SkipPacket();
97 break;
98 }
99 }
100
101 File.clear();
102 File.seekg(Current, std::ios::beg);
103 return Frame.Elapsed;
104}
105
106std::string CarlaReplayer::ReplayFile(std::string Filename, double TimeStart, double Duration,
107 uint32_t ThisFollowId, bool ReplaySensors)
108{
109 std::stringstream Info;
110 std::string s;
111
112 // check to stop if we are replaying another
113 if (Enabled)
114 {
115 Stop();
116 }
117
118 // get the final path + filename
119 std::string Filename2 = GetRecorderFilename(Filename);
120
121 Info << "Replaying File: " << Filename2 << std::endl;
122
123 // try to open
124 File.open(Filename2, std::ios::binary);
125 if (!File.is_open())
126 {
127 Info << "File " << Filename2 << " not found on server\n";
128 Stop();
129 return Info.str();
130 }
131
132 // from start
133 Rewind();
134
135 // check to load map if different
137 {
139 {
140 Info << "Could not load mapfile " << TCHAR_TO_UTF8(*RecInfo.Mapfile) << std::endl;
141 Stop();
142 return Info.str();
143 }
144 Info << "Loading map " << TCHAR_TO_UTF8(*RecInfo.Mapfile) << std::endl;
145 Info << "Replayer will start after map is loaded..." << std::endl;
146
147 // prepare autoplay after map is loaded
148 Autoplay.Enabled = true;
149 Autoplay.Filename = Filename2;
151 Autoplay.TimeStart = TimeStart;
152 Autoplay.Duration = Duration;
153 Autoplay.FollowId = ThisFollowId;
155 Autoplay.ReplaySensors = ReplaySensors;
156 }
157
158 // get Total time of recorder
160 Info << "Total time recorded: " << TotalTime << std::endl;
161
162 // set time to start replayer
163 if (TimeStart < 0.0f)
164 {
165 TimeStart = TotalTime + TimeStart;
166 if (TimeStart < 0.0f)
167 TimeStart = 0.0f;
168 }
169
170 // set time to stop replayer
171 if (Duration > 0.0f)
172 TimeToStop = TimeStart + Duration;
173 else
175
176 Info << "Replaying from " << TimeStart << " s - " << TimeToStop << " s (" << TotalTime << " s) at " <<
177 std::setprecision(1) << std::fixed << TimeFactor << "x" << std::endl;
178
179 if (IgnoreHero)
180 Info << "Ignoring Hero vehicle" << std::endl;
181
182 if (IgnoreSpectator)
183 Info << "Ignoring Spectator camera" << std::endl;
184
185 // set the follow Id
186 FollowId = ThisFollowId;
187
188 bReplaySensors = ReplaySensors;
189 // if we don't need to load a new map, then start
190 if (!Autoplay.Enabled)
191 {
193 // process all events until the time
194 ProcessToTime(TimeStart, true);
195 // mark as enabled
196 Enabled = true;
197 }
198
199 return Info.str();
200}
201
203{
204
205 // check if the autoplay is enabled (means waiting until map is loaded)
206 if (!Autoplay.Enabled)
207 return;
208
209 // disable
210 Autoplay.Enabled = false;
211
212 // check to stop if we are replaying another
213 if (Enabled)
214 {
215 Stop();
216 }
217
218 // try to open
219 File.open(Autoplay.Filename, std::ios::binary);
220 if (!File.is_open())
221 {
222 return;
223 }
224
225 // from start
226 Rewind();
227
228 // get Total time of recorder
230
231 // set time to start replayer
232 double TimeStart = Autoplay.TimeStart;
233 if (TimeStart < 0.0f)
234 {
235 TimeStart = TotalTime + Autoplay.TimeStart;
236 if (TimeStart < 0.0f)
237 TimeStart = 0.0f;
238 }
239
240 // set time to stop replayer
241 if (Autoplay.Duration > 0.0f)
242 TimeToStop = TimeStart + Autoplay.Duration;
243 else
245
246 // set the follow Id
248
250
251 // apply time factor
253
255
256 // process all events until the time
257 ProcessToTime(TimeStart, true);
258
259 // mark as enabled
260 Enabled = true;
261}
262
263void CarlaReplayer::ProcessToTime(double Time, bool IsFirstTime)
264{
265 double Per = 0.0f;
266 double NewTime = CurrentTime + Time;
267 bool bFrameFound = false;
268 bool bExitAtNextFrame = false;
269 bool bExitLoop = false;
270
271 // check if we are in the right frame
272 if (NewTime >= Frame.Elapsed && NewTime < Frame.Elapsed + Frame.DurationThis)
273 {
274 Per = (NewTime - Frame.Elapsed) / Frame.DurationThis;
275 bFrameFound = true;
276 bExitLoop = true;
277 }
278
279 // process all frames until time we want or end
280 while (!File.eof() && !bExitLoop)
281 {
282 // get header
283 ReadHeader();
284
285 // check for a frame packet
286 switch (Header.Id)
287 {
288 // frame
289 case static_cast<char>(CarlaRecorderPacketId::FrameStart):
290 // only read if we are not in the right frame
291 Frame.Read(File);
292 // check if target time is in this frame
293 if (NewTime < Frame.Elapsed + Frame.DurationThis)
294 {
295 Per = (NewTime - Frame.Elapsed) / Frame.DurationThis;
296 bFrameFound = true;
297 }
298 break;
299
300 // visual time for FX
301 case static_cast<char>(CarlaRecorderPacketId::VisualTime):
303 break;
304
305 // events add
306 case static_cast<char>(CarlaRecorderPacketId::EventAdd):
308 break;
309
310 // events del
311 case static_cast<char>(CarlaRecorderPacketId::EventDel):
313 break;
314
315 // events parent
316 case static_cast<char>(CarlaRecorderPacketId::EventParent):
318 break;
319
320 // collisions
321 case static_cast<char>(CarlaRecorderPacketId::Collision):
322 SkipPacket();
323 break;
324
325 // positions
326 case static_cast<char>(CarlaRecorderPacketId::Position):
327 if (bFrameFound)
328 ProcessPositions(IsFirstTime);
329 else
330 SkipPacket();
331 break;
332
333 // states
334 case static_cast<char>(CarlaRecorderPacketId::State):
335 if (bFrameFound)
337 else
338 SkipPacket();
339 break;
340
341 // vehicle animation
342 case static_cast<char>(CarlaRecorderPacketId::AnimVehicle):
343 if (bFrameFound)
345 else
346 SkipPacket();
347 break;
348
349 // vehicle wheels animation
350 case static_cast<char>(CarlaRecorderPacketId::AnimVehicleWheels):
351 if (bFrameFound)
353 else
354 SkipPacket();
355 break;
356
357 // walker animation
358 case static_cast<char>(CarlaRecorderPacketId::AnimWalker):
359 if (bFrameFound)
361 else
362 SkipPacket();
363 break;
364
365 // biker animation
366 case static_cast<char>(CarlaRecorderPacketId::AnimBiker):
367 if (bFrameFound)
369 else
370 SkipPacket();
371 break;
372
373 // vehicle light animation
374 case static_cast<char>(CarlaRecorderPacketId::VehicleLight):
375 if (bFrameFound)
377 else
378 SkipPacket();
379 break;
380
381 // vehicle door animation
382 case static_cast<char>(CarlaRecorderPacketId::VehicleDoor):
383 if (bFrameFound)
385 else
386 SkipPacket();
387 break;
388
389 // scene lights animation
390 case static_cast<char>(CarlaRecorderPacketId::SceneLight):
391 if (bFrameFound)
393 else
394 SkipPacket();
395 break;
396
397 // walker bones
398 case static_cast<char>(CarlaRecorderPacketId::WalkerBones):
399 if (bFrameFound)
401 else
402 SkipPacket();
403 break;
404
405 // frame end
406 case static_cast<char>(CarlaRecorderPacketId::FrameEnd):
407 if (bFrameFound)
408 bExitLoop = true;
409 break;
410
411 // unknown packet, just skip
412 default:
413 // skip packet
414 SkipPacket();
415 break;
416
417 }
418 }
419
420 // update all positions
421 if (Enabled && bFrameFound)
422 {
423 UpdatePositions(Per, Time);
424 }
425
426 // save current time
427 CurrentTime = NewTime;
428
429 // stop replay?
430 if (CurrentTime >= TimeToStop)
431 {
432 // keep actors in scene and let them continue with autopilot
433 Stop(true);
434 }
435}
436
438{
441
442 // set the visual time
444}
445
447{
448 uint16_t i, Total;
450
451 // process creation events
452 ReadValue<uint16_t>(File, Total);
453 for (i = 0; i < Total; ++i)
454 {
455 EventAdd.Read(File);
456
457 // auto Result = CallbackEventAdd(
458 auto Result = Helper.ProcessReplayerEventAdd(
459 EventAdd.Location,
460 EventAdd.Rotation,
461 EventAdd.Description,
462 EventAdd.DatabaseId,
466
467 switch (Result.first)
468 {
469 // actor not created
470 case 0:
471 UE_LOG(LogCarla, Log, TEXT("actor could not be created"));
472 break;
473
474 // actor created but with different id
475 case 1:
476 // mapping id (recorded Id is a new Id in replayer)
477 MappedId[EventAdd.DatabaseId] = Result.second;
478 break;
479
480 // actor reused from existing
481 case 2:
482 // mapping id (say desired Id is mapped to what)
483 MappedId[EventAdd.DatabaseId] = Result.second;
484 break;
485
486 // actor ignored (either Hero or Spectator)
487 case 3:
488 UE_LOG(LogCarla, Log, TEXT("ignoring actor from replayer (Hero or Spectator)"));
489 break;
490
491 }
492
493 // check to mark if actor is a hero vehicle or not
494 if (Result.first > 0 && Result.first < 3)
495 {
496 // init
497 IsHeroMap[Result.second] = false;
498 for (const auto &Item : EventAdd.Description.Attributes)
499 {
500 if (Item.Id == "role_name" && Item.Value == "hero")
501 {
502 // mark as hero
503 IsHeroMap[Result.second] = true;
504 break;
505 }
506 }
507 }
508 }
509}
510
512{
513 uint16_t i, Total;
515
516 // process destroy events
517 ReadValue<uint16_t>(File, Total);
518 for (i = 0; i < Total; ++i)
519 {
520 EventDel.Read(File);
522 MappedId.erase(EventDel.DatabaseId);
523 }
524}
525
527{
528 uint16_t i, Total;
530 std::stringstream Info;
531
532 // process parenting events
533 ReadValue<uint16_t>(File, Total);
534 for (i = 0; i < Total; ++i)
535 {
536 EventParent.Read(File);
538 }
539}
540
542{
543 uint16_t i, Total;
544 CarlaRecorderStateTrafficLight StateTrafficLight;
545 std::stringstream Info;
546
547 // read Total traffic light states
548 ReadValue<uint16_t>(File, Total);
549 for (i = 0; i < Total; ++i)
550 {
551 StateTrafficLight.Read(File);
552
553 StateTrafficLight.DatabaseId = MappedId[StateTrafficLight.DatabaseId];
554 if (!Helper.ProcessReplayerStateTrafficLight(StateTrafficLight))
555 {
556 UE_LOG(LogCarla,
557 Log,
558 TEXT("callback state traffic light %d called but didn't work"),
559 StateTrafficLight.DatabaseId);
560 }
561 }
562}
563
565{
566 uint16_t i, Total;
568 std::stringstream Info;
569
570 // read Total Vehicles
571 ReadValue<uint16_t>(File, Total);
572 for (i = 0; i < Total; ++i)
573 {
574 Vehicle.Read(File);
575 Vehicle.DatabaseId = MappedId[Vehicle.DatabaseId];
576 // check if ignore this actor
577 if (!(IgnoreHero && IsHeroMap[Vehicle.DatabaseId]))
578 {
580 }
581 }
582}
583
585{
586 uint16_t i, Total;
587
588 // read Total Vehicles
589 ReadValue<uint16_t>(File, Total);
590 for (i = 0; i < Total; ++i)
591 {
594 Vehicle.DatabaseId = MappedId[Vehicle.DatabaseId];
595 // check if ignore this actor
596 if (!(IgnoreHero && IsHeroMap[Vehicle.DatabaseId]))
597 {
599 }
600 }
601}
602
604{
605 uint16_t i, Total;
607 std::stringstream Info;
608
609 // read Total walkers
610 ReadValue<uint16_t>(File, Total);
611 for (i = 0; i < Total; ++i)
612 {
613 Walker.Read(File);
614 Walker.DatabaseId = MappedId[Walker.DatabaseId];
615 // check if ignore this actor
616 if (!(IgnoreHero && IsHeroMap[Walker.DatabaseId]))
617 {
619 }
620 }
621}
622
624{
625 uint16_t i, Total;
627 std::stringstream Info;
628
629 ReadValue<uint16_t>(File, Total);
630 for (i = 0; i < Total; ++i)
631 {
632 Biker.Read(File);
633 Biker.DatabaseId = MappedId[Biker.DatabaseId];
634 if (!(IgnoreHero && IsHeroMap[Biker.DatabaseId]))
635 {
637 }
638 }
639}
640
642{
643 uint16_t Total;
644 CarlaRecorderLightVehicle LightVehicle;
645
646 // read Total walkers
647 ReadValue<uint16_t>(File, Total);
648 for (uint16_t i = 0; i < Total; ++i)
649 {
650 LightVehicle.Read(File);
651 LightVehicle.DatabaseId = MappedId[LightVehicle.DatabaseId];
652 // check if ignore this actor
653 if (!(IgnoreHero && IsHeroMap[LightVehicle.DatabaseId]))
654 {
656 }
657 }
658}
659
661{
662 uint16_t Total;
663 CarlaRecorderDoorVehicle DoorVehicle;
664
665 // read Total walkers
666 ReadValue<uint16_t>(File, Total);
667 for (uint16_t i = 0; i < Total; ++i)
668 {
669 DoorVehicle.Read(File);
670 DoorVehicle.DatabaseId = MappedId[DoorVehicle.DatabaseId];
671 // check if ignore this actor
672 if (!(IgnoreHero && IsHeroMap[DoorVehicle.DatabaseId]))
673 {
675 }
676 }
677}
678
680{
681 uint16_t Total;
682 CarlaRecorderLightScene LightScene;
683
684 // read Total light events
685 ReadValue<uint16_t>(File, Total);
686 for (uint16_t i = 0; i < Total; ++i)
687 {
688 LightScene.Read(File);
690 }
691}
692
694{
695 uint16_t i, Total;
696
697 // save current as previous
698 PrevPos = std::move(CurrPos);
699
700 // read all positions
701 ReadValue<uint16_t>(File, Total);
702 CurrPos.clear();
703 CurrPos.reserve(Total);
704 for (i = 0; i < Total; ++i)
705 {
707 Pos.Read(File);
708 // assign mapped Id
709 auto NewId = MappedId.find(Pos.DatabaseId);
710 if (NewId != MappedId.end())
711 {
712 Pos.DatabaseId = NewId->second;
713 }
714 else
715 UE_LOG(LogCarla, Log, TEXT("Actor not found when trying to move from replayer (id. %d)"), Pos.DatabaseId);
716 CurrPos.push_back(std::move(Pos));
717 }
718
719 // check to copy positions the first time
720 if (IsFirstTime)
721 {
722 PrevPos.clear();
723 }
724}
725
727{
728 uint16_t i, Total;
730 std::stringstream Info;
731
732 // read Total walkers
733 ReadValue<uint16_t>(File, Total);
734 for (i = 0; i < Total; ++i)
735 {
736 Walker.Read(File);
737 Walker.DatabaseId = MappedId[Walker.DatabaseId];
738 // check if ignore this actor
739 if (!(IgnoreHero && IsHeroMap[Walker.DatabaseId]))
740 {
742 }
743 }
744}
745
746void CarlaReplayer::UpdatePositions(double Per, double DeltaTime)
747{
748 unsigned int i;
749 uint32_t NewFollowId = 0;
750 std::unordered_map<int, int> TempMap;
751
752 // map the id of all previous positions to its index
753 for (i = 0; i < PrevPos.size(); ++i)
754 {
755 TempMap[PrevPos[i].DatabaseId] = i;
756 }
757
758 // get the Id of the actor to follow
759 if (FollowId != 0)
760 {
761 auto NewId = MappedId.find(FollowId);
762 if (NewId != MappedId.end())
763 {
764 NewFollowId = NewId->second;
765 }
766 }
767
768 // go through each actor and update
769 for (auto &Pos : CurrPos)
770 {
771 // check if ignore this actor (hero) or the spectator (id == 1)
772 if (!(IgnoreHero && IsHeroMap[Pos.DatabaseId]) &&
773 !(IgnoreSpectator && Pos.DatabaseId == 1))
774 {
775 // check if exist a previous position
776 auto Result = TempMap.find(Pos.DatabaseId);
777 if (Result != TempMap.end())
778 {
779 // check if time factor is high
780 if (TimeFactor >= 2.0)
781 // assign first position
782 InterpolatePosition(PrevPos[Result->second], Pos, 0.0, DeltaTime);
783 else
784 // interpolate
785 InterpolatePosition(PrevPos[Result->second], Pos, Per, DeltaTime);
786 }
787 else
788 {
789 // assign last position (we don't have previous one)
790 InterpolatePosition(Pos, Pos, 0.0, DeltaTime);
791 }
792 }
793
794 // move the camera to follow this actor if required
795 if (NewFollowId != 0)
796 {
797 if (NewFollowId == Pos.DatabaseId)
798 Helper.SetCameraPosition(NewFollowId, FVector(-1000, 0, 500), FQuat::MakeFromEuler({0, -25, 0}));
799 }
800 }
801}
802
803// interpolate a position (transform, velocity...)
805 const CarlaRecorderPosition &Pos1,
806 const CarlaRecorderPosition &Pos2,
807 double Per,
808 double DeltaTime)
809{
810 // call the callback
811 Helper.ProcessReplayerPosition(Pos1, Pos2, Per, DeltaTime, IgnoreSpectator);
812}
813
814// tick for the replayer
815void CarlaReplayer::Tick(float Delta)
816{
817 TRACE_CPUPROFILER_EVENT_SCOPE(CarlaReplayer::Tick);
818 // check if there are events to process
819 if (Enabled)
820 {
821 ProcessToTime(Delta * TimeFactor, false);
822 }
823}
std::string GetRecorderFilename(std::string Filename)
void ProcessReplayerWalkerBones(const CarlaRecorderWalkerBones &Walker)
bool ProcessReplayerFinish(bool bApplyAutopilot, bool bIgnoreHero, std::unordered_map< uint32_t, bool > &IsHero)
void ProcessReplayerAnimVehicleWheels(CarlaRecorderAnimWheels Vehicle)
void ProcessReplayerLightScene(CarlaRecorderLightScene LightScene)
void ProcessReplayerDoorVehicle(CarlaRecorderDoorVehicle DoorVehicle)
void ProcessReplayerAnimWalker(CarlaRecorderAnimWalker Walker)
bool ProcessReplayerStateTrafficLight(CarlaRecorderStateTrafficLight State)
bool ProcessReplayerEventParent(uint32_t ChildId, uint32_t ParentId)
void ProcessReplayerAnimVehicle(CarlaRecorderAnimVehicle Vehicle)
bool ProcessReplayerPosition(CarlaRecorderPosition Pos1, CarlaRecorderPosition Pos2, double Per, double DeltaTime, bool bIgnoreSpectator)
bool ProcessReplayerEventDel(uint32_t DatabaseId)
void ProcessReplayerLightVehicle(CarlaRecorderLightVehicle LightVehicle)
std::pair< int, uint32_t > ProcessReplayerEventAdd(FVector Location, FVector Rotation, CarlaRecorderActorDescription Description, uint32_t DesiredId, bool bIgnoreHero, bool bIgnoreSpectator, bool ReplaySensors)
void ProcessReplayerAnimBiker(CarlaRecorderAnimBiker Biker)
bool SetCameraPosition(uint32_t Id, FVector Offset, FQuat Rotation)
void ProcessEventsDel(void)
void ProcessDoorVehicle(void)
std::vector< CarlaRecorderPosition > PrevPos
void Rewind(void)
void ProcessVisualTime(void)
void ProcessLightVehicle(void)
double GetTotalTime(void)
std::vector< CarlaRecorderPosition > CurrPos
void ProcessAnimVehicleWheels(void)
void InterpolatePosition(const CarlaRecorderPosition &Start, const CarlaRecorderPosition &End, double Per, double DeltaTime)
void ProcessAnimVehicle(void)
std::string ReplayFile(std::string Filename, double TimeStart=0.0f, double Duration=0.0f, uint32_t FollowId=0, bool ReplaySensors=false)
void ProcessWalkerBones(void)
void Tick(float Time)
void ProcessPositions(bool IsFirstTime=false)
void ProcessEventsParent(void)
void UpdatePositions(double Per, double DeltaTime)
uint32_t FollowId
void ProcessEventsAdd(void)
static PlayAfterLoadMap Autoplay
std::ifstream File
UCarlaEpisode * Episode
CarlaRecorderFrame Frame
void ProcessAnimWalker(void)
void ProcessStates(void)
void ProcessAnimBiker(void)
CarlaRecorderInfo RecInfo
CarlaReplayerHelper Helper
void ProcessLightScene(void)
void CheckPlayAfterMapLoaded(void)
std::unordered_map< uint32_t, bool > IsHeroMap
void ProcessToTime(double Time, bool IsFirstTime=false)
std::unordered_map< uint32_t, uint32_t > MappedId
void Stop(bool KeepActors=false)
const FString & GetMapName() const
Return the name of the map loaded in this episode.
void SetVisualGameTime(double Time)
bool LoadNewEpisode(const FString &MapString, bool ResetSettings=true)
Load a new map and start a new episode.
void Read(std::istream &InFile)
void Read(std::istream &InFile)
void Read(std::istream &InFile)
void Read(std::istream &InFile)
void Read(std::istream &File)
void Read(std::istream &InFile)
void Read(std::istream &InFile)
void Read(std::istream &InFile)
void Read(std::istream &InFile)
void Read(std::ifstream &InFile)
void Read(std::ifstream &InFile)