CARLA
Loading...
Searching...
No Matches
CarlaRecorderQuery.cpp
Go to the documentation of this file.
1// Copyright (c) 2026 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
9#include "CarlaRecorder.h"
11
16
17#include <ctime>
18#include <sstream>
19#include <string_view>
20#include <string>
21
22// Clang 16 does not support C++20's std::format
23#if defined(ENABLE_STD_FORMAT) && __has_include(<format>)
24#define HAS_FORMAT
25#include <format>
26#endif
27
28template <typename V>
29requires (
30 std::remove_reference_t<V>::Dim <= 3)
31static std::string FormatVectorLike(V&& v)
32{
33#ifndef HAS_FORMAT
34 char buffer[256];
35#endif
36 constexpr auto Dim = std::remove_reference_t<V>::Dim;
37 if constexpr (Dim == 1)
38 {
39 const auto& [x] = v;
40#ifdef HAS_FORMAT
41 return std::format("({})", x);
42#else
43 auto n = snprintf(buffer, sizeof(buffer), "(%f)", (double)x);
44 if (n < 0)
45 return "<FORMAT-ERRROR>";
46 return std::string(buffer, n);
47#endif
48 }
49 else if constexpr (Dim == 2)
50 {
51 const auto& [x, y] = v;
52#ifdef HAS_FORMAT
53 return std::format("({}, {})", x, y);
54#else
55 auto n = snprintf(buffer, sizeof(buffer), "(%f, %f)", (double)x, (double)y);
56 if (n < 0)
57 return "<FORMAT-ERRROR>";
58 return std::string(buffer, n);
59#endif
60 }
61 else if constexpr (Dim == 3)
62 {
63 const auto& [x, y, z] = v;
64#ifdef HAS_FORMAT
65 return std::format("({}, {}, {})", x, y, z);
66#else
67 auto n = snprintf(buffer, sizeof(buffer), "(%f, %f, %f)", (double)x, (double)y, (double)z);
68 if (n < 0)
69 return "<FORMAT-ERRROR>";
70 return std::string(buffer, n);
71#endif
72 }
73}
74
75template <typename V>
76static std::string FormatCurveLike(V&& v)
77{
78 std::string r;
79 r += "[";
80 for (auto& point : v)
81 {
83 r += ',';
84 }
85 r += "]";
86 return r;
87}
88
90{
91 if (File.eof())
92 {
93 return false;
94 }
95
96 ReadValue<char>(File, Header.Id);
97 ReadValue<uint32_t>(File, Header.Size);
98
99 return true;
100}
101
103{
104 File.seekg(Header.Size, std::ios::cur);
105}
106
107inline bool CarlaRecorderQuery::CheckFileInfo(std::stringstream& Info)
108{
109 // read Info
111
112 // check magic string
113 if (RecInfo.Magic != "CARLA_RECORDER")
114 {
115 Info << "File is not a CARLA recorder" << std::endl;
116 return false;
117 }
118
119 // show general Info
120 Info << "Version: " << RecInfo.Version << std::endl;
121 Info << "Map: " << TCHAR_TO_UTF8(*RecInfo.Mapfile) << std::endl;
122#ifdef _WIN32
123 struct tm Tmp;
124 localtime_s(&Tmp, &RecInfo.Date);
125 auto TimeInfo = &Tmp;
126#else
127 auto TimeInfo = localtime(&RecInfo.Date);
128#endif
129 char DateStr[100];
130 strftime(DateStr, sizeof(DateStr), "%x %X", TimeInfo);
131 Info << "Date: " << DateStr << std::endl << std::endl;
132
133 return true;
134}
135
136std::string CarlaRecorderQuery::QueryInfo(std::string Filename, bool bShowAll)
137{
138 std::stringstream Info;
139
140 // get the final path + filename
141 std::string Filename2 = GetRecorderFilename(Filename);
142
143 // try to open
144 File.open(Filename2, std::ios::binary);
145 if (!File.is_open())
146 {
147 Info << "File " << Filename2 << " not found on server\n";
148 return Info.str();
149 }
150
151 uint16_t i, Total;
152 bool bFramePrinted = false;
153
154 // lambda for repeating task
155 auto PrintFrame = [this](std::stringstream& Info)
156 {
157 Info << "Frame " << Frame.Id << " at " << Frame.Elapsed << " seconds\n";
158 };
159
160 if (!CheckFileInfo(Info))
161 return Info.str();
162
163 // parse only frames
164 while (File)
165 {
166 // get header
167 if (!ReadHeader())
168 {
169 break;
170 }
171
172 // check for a frame packet
173 switch (Header.Id)
174 {
175 // frame
176 case static_cast<char>(CarlaRecorderPacketId::FrameStart):
177 Frame.Read(File);
178 if (bShowAll)
179 {
180 PrintFrame(Info);
181 bFramePrinted = true;
182 }
183 else
184 bFramePrinted = false;
185 break;
186
187 // events add
188 case static_cast<char>(CarlaRecorderPacketId::EventAdd):
189 ReadValue<uint16_t>(File, Total);
190 if (Total > 0 && !bFramePrinted)
191 {
192 PrintFrame(Info);
193 bFramePrinted = true;
194 }
195 for (i = 0; i < Total; ++i)
196 {
197 // add
199 Info << " Create " << EventAdd.DatabaseId << ": " << TCHAR_TO_UTF8(*EventAdd.Description.Id) <<
200 " (" <<
201 static_cast<int>(EventAdd.Type) << ") at (" << EventAdd.Location.X << ", " <<
202 EventAdd.Location.Y << ", " << EventAdd.Location.Z << ")" << std::endl;
203 for (auto& Att : EventAdd.Description.Attributes)
204 {
205 Info << " " << TCHAR_TO_UTF8(*Att.Id) << " = " << TCHAR_TO_UTF8(*Att.Value) << std::endl;
206 }
207 }
208 break;
209
210 // weather
211 case static_cast<char>(CarlaRecorderPacketId::Weather):
212 ReadValue<uint16_t>(File, Total);
213 if (Total > 0 && !bFramePrinted)
214 {
215 PrintFrame(Info);
216 bFramePrinted = true;
217 }
218
219 Info << " Weathers: " << Total << std::endl;
220 for (i = 0; i < Total; ++i)
221 {
223 Info << " Cloudiness: " << Weather.Cloudiness
224 << " Precipitation: " << Weather.Precipitation
225 << " PrecipitationDeposits: " << Weather.PrecipitationDeposits
226 << " WindIntensity: " << Weather.WindIntensity
227 << " SunAzimuthAngle: " << Weather.SunAzimuthAngle
228 << " SunAltitudeAngle: " << Weather.SunAltitudeAngle
229 << " FogDensity: " << Weather.FogDensity
230 << " FogDistance: " << Weather.FogDistance
231 << " FogFalloff: " << Weather.FogFalloff
232 << " Wetness: " << Weather.Wetness
233 << " ScatteringIntensity: " << Weather.ScatteringIntensity
234 << " MieScatteringScale: " << Weather.MieScatteringScale
235 << " RayleighScatteringScale: " << Weather.RayleighScatteringScale
236 << " DustStorm: " << Weather.DustStorm << "\n";
237 }
238 break;
239
240 // events del
241 case static_cast<char>(CarlaRecorderPacketId::EventDel):
242 ReadValue<uint16_t>(File, Total);
243 if (Total > 0 && !bFramePrinted)
244 {
245 PrintFrame(Info);
246 bFramePrinted = true;
247 }
248 for (i = 0; i < Total; ++i)
249 {
251 Info << " Destroy " << EventDel.DatabaseId << "\n";
252 }
253 break;
254
255 // events parenting
256 case static_cast<char>(CarlaRecorderPacketId::EventParent):
257 ReadValue<uint16_t>(File, Total);
258 if (Total > 0 && !bFramePrinted)
259 {
260 PrintFrame(Info);
261 bFramePrinted = true;
262 }
263 for (i = 0; i < Total; ++i)
264 {
266 Info << " Parenting " << EventParent.DatabaseId << " with " << EventParent.DatabaseIdParent <<
267 " (parent)\n";
268 }
269 break;
270
271 // collisions
272 case static_cast<char>(CarlaRecorderPacketId::Collision):
273 ReadValue<uint16_t>(File, Total);
274 if (Total > 0 && !bFramePrinted)
275 {
276 PrintFrame(Info);
277 bFramePrinted = true;
278 }
279 for (i = 0; i < Total; ++i)
280 {
282 Info << " Collision id " << Collision.Id << " between " << Collision.DatabaseId1;
284 Info << " (hero) ";
285 Info << " with " << Collision.DatabaseId2;
287 Info << " (hero) ";
288 Info << std::endl;
289 }
290 break;
291
292 // positions
293 case static_cast<char>(CarlaRecorderPacketId::Position):
294 if (bShowAll)
295 {
296 ReadValue<uint16_t>(File, Total);
297 if (Total > 0 && !bFramePrinted)
298 {
299 PrintFrame(Info);
300 bFramePrinted = true;
301 }
302 Info << " Positions: " << Total << std::endl;
303 for (i = 0; i < Total; ++i)
304 {
306 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;
307 }
308 }
309 else
310 SkipPacket();
311 break;
312
313 // traffic light
314 case static_cast<char>(CarlaRecorderPacketId::State):
315 if (bShowAll)
316 {
317 ReadValue<uint16_t>(File, Total);
318 if (Total > 0 && !bFramePrinted)
319 {
320 PrintFrame(Info);
321 bFramePrinted = true;
322 }
323 Info << " State traffic lights: " << Total << std::endl;
324 for (i = 0; i < Total; ++i)
325 {
327 Info << " Id: " << StateTraffic.DatabaseId << " state: " << static_cast<char>(0x30 + StateTraffic.State) << " frozen: " <<
328 StateTraffic.IsFrozen << " elapsedTime: " << StateTraffic.ElapsedTime << std::endl;
329 }
330 }
331 else
332 SkipPacket();
333 break;
334
335 // vehicle animations
336 case static_cast<char>(CarlaRecorderPacketId::AnimVehicle):
337 if (bShowAll)
338 {
339 ReadValue<uint16_t>(File, Total);
340 if (Total > 0 && !bFramePrinted)
341 {
342 PrintFrame(Info);
343 bFramePrinted = true;
344 }
345 Info << " Vehicle animations: " << Total << std::endl;
346 for (i = 0; i < Total; ++i)
347 {
349 Info << " Id: " << Vehicle.DatabaseId << " Steering: " << Vehicle.Steering << " Throttle: " << Vehicle.Throttle << " Brake: " << Vehicle.Brake << " Handbrake: " << Vehicle.bHandbrake << " Gear: " << Vehicle.Gear << std::endl;
350 }
351 }
352 else
353 SkipPacket();
354 break;
355
356 // vehicle wheel animations
357 case static_cast<char>(CarlaRecorderPacketId::AnimVehicleWheels):
358 if (bShowAll)
359 {
360 ReadValue<uint16_t>(File, Total);
361 if (Total > 0 && !bFramePrinted)
362 {
363 PrintFrame(Info);
364 bFramePrinted = true;
365 }
366 Info << " Vehicle wheel animations: " << Total << std::endl;
367 for (i = 0; i < Total; ++i)
368 {
370 Info << " Id: " << VehicleWheels.DatabaseId << " Wheels: " << VehicleWheels.WheelValues.size() << std::endl;
371 for (const WheelInfo &Wheel : VehicleWheels.WheelValues)
372 {
373 Info << " Location: " << static_cast<int>(Wheel.Location) <<
374 " Steering: " << Wheel.SteeringAngle <<
375 " Tire rotation: " << Wheel.TireRotation << std::endl;
376 }
377 }
378 }
379 else
380 SkipPacket();
381 break;
382
383 // walker animations
384 case static_cast<char>(CarlaRecorderPacketId::AnimWalker):
385 if (bShowAll)
386 {
387 ReadValue<uint16_t>(File, Total);
388 if (Total > 0 && !bFramePrinted)
389 {
390 PrintFrame(Info);
391 bFramePrinted = true;
392 }
393 Info << " Walker animations: " << Total << std::endl;
394 for (i = 0; i < Total; ++i)
395 {
397 Info << " Id: " << Walker.DatabaseId << " speed: " << Walker.Speed << std::endl;
398 }
399 }
400 else
401 SkipPacket();
402 break;
403
404 // biker animations
405 case static_cast<char>(CarlaRecorderPacketId::AnimBiker):
406 if (bShowAll)
407 {
408 ReadValue<uint16_t>(File, Total);
409 if (Total > 0 && !bFramePrinted)
410 {
411 PrintFrame(Info);
412 bFramePrinted = true;
413 }
414 Info << " Biker animations: " << Total << std::endl;
415 for (i = 0; i < Total; ++i)
416 {
417 Biker.Read(File);
418 Info << " Id: " << Biker.DatabaseId << " Forward speed: " << Biker.ForwardSpeed <<
419 " Engine rotation: " << Biker.EngineRotation << std::endl;
420 }
421 }
422 else
423 SkipPacket();
424 break;
425
426 // vehicle door animations
427 case static_cast<char>(CarlaRecorderPacketId::VehicleDoor):
428 if (bShowAll)
429 {
430 ReadValue<uint16_t>(File, Total);
431 if (Total > 0 && !bFramePrinted)
432 {
433 PrintFrame(Info);
434 bFramePrinted = true;
435 }
436 Info << " Vehicle door animations: " << Total << std::endl;
437 for (i = 0; i < Total; ++i)
438 {
440
442 doorVehicle = DoorVehicle.Doors;
443 EVehicleDoor eDoorVehicle = static_cast<EVehicleDoor>(doorVehicle);
444 std::string opened_doors_list;
445
446 Info << " Id: " << DoorVehicle.DatabaseId << std::endl;
447 Info << " Doors opened: ";
448 if (eDoorVehicle == EVehicleDoor::FL)
449 Info << " Front Left " << std::endl;
450 if (eDoorVehicle == EVehicleDoor::FR)
451 Info << " Front Right " << std::endl;
452 if (eDoorVehicle == EVehicleDoor::RL)
453 Info << " Rear Left " << std::endl;
454 if (eDoorVehicle == EVehicleDoor::RR)
455 Info << " Rear Right " << std::endl;
456 if (eDoorVehicle == EVehicleDoor::Hood)
457 Info << " Hood " << std::endl;
458 if (eDoorVehicle == EVehicleDoor::Trunk)
459 Info << " Trunk " << std::endl;
460 if (eDoorVehicle == EVehicleDoor::All)
461 Info << " All " << std::endl;
462 }
463 }
464 else
465 SkipPacket();
466 break;
467
468
469 // vehicle light animations
470 case static_cast<char>(CarlaRecorderPacketId::VehicleLight):
471 if (bShowAll)
472 {
473 ReadValue<uint16_t>(File, Total);
474 if (Total > 0 && !bFramePrinted)
475 {
476 PrintFrame(Info);
477 bFramePrinted = true;
478 }
479 Info << " Vehicle light animations: " << Total << std::endl;
480 for (i = 0; i < Total; ++i)
481 {
483
485 FVehicleLightState State(LightState);
486 std::string enabled_lights_list;
487 if (State.Position)
488 enabled_lights_list += "Position ";
489 if (State.LowBeam)
490 enabled_lights_list += "LowBeam ";
491 if (State.HighBeam)
492 enabled_lights_list += "HighBeam ";
493 if (State.Brake)
494 enabled_lights_list += "Brake ";
495 if (State.RightBlinker)
496 enabled_lights_list += "RightBlinker ";
497 if (State.LeftBlinker)
498 enabled_lights_list += "LeftBlinker ";
499 if (State.Reverse)
500 enabled_lights_list += "Reverse ";
501 if (State.Interior)
502 enabled_lights_list += "Interior ";
503 if (State.Fog)
504 enabled_lights_list += "Fog ";
505 if (State.Special1)
506 enabled_lights_list += "Special1 ";
507 if (State.Special2)
508 enabled_lights_list += "Special2 ";
509
510 if (enabled_lights_list.size())
511 {
512 Info << " Id: " << LightVehicle.DatabaseId << " " <<
513 enabled_lights_list.substr(0, enabled_lights_list.size() - 1) << std::endl;
514 }
515 else
516 {
517 Info << " Id: " << LightVehicle.DatabaseId << " None" << std::endl;
518 }
519 }
520 }
521 else
522 SkipPacket();
523 break;
524
525 // scene light animations
526 case static_cast<char>(CarlaRecorderPacketId::SceneLight):
527 if (bShowAll)
528 {
529 ReadValue<uint16_t>(File, Total);
530 if (Total > 0 && !bFramePrinted)
531 {
532 PrintFrame(Info);
533 bFramePrinted = true;
534 }
535 Info << " Scene light changes: " << Total << std::endl;
536 for (i = 0; i < Total; ++i)
537 {
539 Info << " Id: " << LightScene.LightId << " enabled: " << (LightScene.bOn ? "True" : "False")
540 << " intensity: " << LightScene.Intensity
541 << " RGB_color: (" << LightScene.Color.R << ", " << LightScene.Color.G << ", " << LightScene.Color.B << ")"
542 << std::endl;
543 }
544 }
545 else
546 SkipPacket();
547 break;
548
549 // dynamic actor kinematics
550 case static_cast<char>(CarlaRecorderPacketId::Kinematics):
551 if (bShowAll)
552 {
553 ReadValue<uint16_t>(File, Total);
554 if (Total > 0 && !bFramePrinted)
555 {
556 PrintFrame(Info);
557 bFramePrinted = true;
558 }
559 Info << " Dynamic actors: " << Total << std::endl;
560 for (i = 0; i < Total; ++i)
561 {
563 Info << " Id: " << Kinematics.DatabaseId << " linear_velocity: ("
564 << Kinematics.LinearVelocity.X << ", " << Kinematics.LinearVelocity.Y << ", " << Kinematics.LinearVelocity.Z << ")"
565 << " angular_velocity: ("
567 << std::endl;
568 }
569 }
570 else
571 SkipPacket();
572 break;
573
574 // actors bounding boxes
575 case static_cast<char>(CarlaRecorderPacketId::BoundingBox):
576 if (bShowAll)
577 {
578 ReadValue<uint16_t>(File, Total);
579 if (Total > 0 && !bFramePrinted)
580 {
581 PrintFrame(Info);
582 bFramePrinted = true;
583 }
584 Info << " Actor bounding boxes: " << Total << std::endl;
585 for (i = 0; i < Total; ++i)
586 {
588 Info << " Id: " << ActorBoundingBox.DatabaseId << " origin: ("
592 << " extension: ("
596 << std::endl;
597 }
598 }
599 else
600 SkipPacket();
601 break;
602
603 // actors trigger volumes
604 case static_cast<char>(CarlaRecorderPacketId::TriggerVolume):
605 if (bShowAll)
606 {
607 ReadValue<uint16_t>(File, Total);
608 if (Total > 0 && !bFramePrinted)
609 {
610 PrintFrame(Info);
611 bFramePrinted = true;
612 }
613 Info << " Actor trigger volumes: " << Total << std::endl;
614 for (i = 0; i < Total; ++i)
615 {
617 Info << " Id: " << ActorBoundingBox.DatabaseId << " origin: ("
621 << " extension: ("
625 << std::endl;
626 }
627 }
628 else
629 SkipPacket();
630 break;
631
632 // visual time
633 case static_cast<char>(CarlaRecorderPacketId::VisualTime):
634 if (bShowAll)
635 {
636 if (!bFramePrinted)
637 {
638 PrintFrame(Info);
639 bFramePrinted = true;
640 }
641
643 Info << " Current visual time: " << VisualTime.Time << std::endl;
644 }
645 else
646 SkipPacket();
647 break;
648
649 // Platform time
650 case static_cast<char>(CarlaRecorderPacketId::PlatformTime):
651 if (bShowAll)
652 {
653 if (!bFramePrinted)
654 {
655 PrintFrame(Info);
656 bFramePrinted = true;
657 }
658
660 Info << " Current platform time: " << PlatformTime.Time << std::endl;
661 }
662 else
663 SkipPacket();
664 break;
665
666 case static_cast<char>(CarlaRecorderPacketId::PhysicsControl):
667 if (bShowAll)
668 {
669 ReadValue<uint16_t>(File, Total);
670 if (Total > 0 && !bFramePrinted)
671 {
672 PrintFrame(Info);
673 bFramePrinted = true;
674 }
675
676 Info << " Physics Control events: " << Total << '\n';
677 for (i = 0; i < Total; ++i)
678 {
682 Info << " Id: " << PhysicsControl.DatabaseId << '\n'
683 << " max_torque = " << Control.max_torque << '\n'
684 << " max_rpm = " << Control.max_rpm << '\n'
685 << " MOI = " << Control.rev_up_moi << '\n'
686 << " rev_down_rate = " << Control.rev_down_rate << '\n'
687 << " differential_type = " << Control.differential_type << '\n'
688 << " front_rear_split = " << Control.front_rear_split << '\n'
689 << " use_gear_auto_box = " << (Control.use_automatic_gears ? "true" : "false") << '\n'
690 << " gear_change_time = " << Control.gear_change_time << '\n'
691 << " final_ratio = " << Control.final_ratio << '\n'
692 << " change_up_rpm = " << Control.change_up_rpm << '\n'
693 << " change_down_rpm = " << Control.change_down_rpm << '\n'
694 << " transmission_efficiency = " << Control.transmission_efficiency << '\n'
695 << " mass = " << Control.mass << '\n'
696 << " drag_coefficient = " << Control.drag_coefficient << '\n'
697 << " center_of_mass = " << "(" << Control.center_of_mass.x << ", " << Control.center_of_mass.y << ", " << Control.center_of_mass.z << ")" << '\n';
698 Info << " torque_curve =";
699 for (auto& vec : Control.torque_curve)
700 {
701 Info << " (" << vec.x << ", " << vec.y << ")";
702 }
703 Info << '\n';
704 Info << " steering_curve =";
705 for (auto& vec : Control.steering_curve)
706 {
707 Info << " (" << vec.x << ", " << vec.y << ")";
708 }
709 Info << '\n';
710 Info << " forward_gear_ratios:" << '\n';
711 uint32_t count = 0;
712 for (auto& Gear : Control.forward_gear_ratios)
713 {
714 Info << " gear " << count << ": ratio " << Gear << '\n';
715 ++count;
716 }
717 Info << " reverse_gear_ratios:" << '\n';
718 count = 0;
719 for (auto& Gear : Control.reverse_gear_ratios)
720 {
721 Info << " gear " << count << ": ratio " << Gear << '\n';
722 ++count;
723 }
724 Info << " wheels:";
725 size_t Index = 0;
726 for (auto& Wheel : Control.wheels)
727 {
728 Info << "\nwheel #" << Index << ":\n"
729 " axle_type: " << Wheel.axle_type <<
730 " offset: " << FormatVectorLike(Wheel.offset) <<
731 " wheel_radius: " << Wheel.wheel_radius <<
732 " wheel_width: " << Wheel.wheel_width <<
733 " wheel_mass: " << Wheel.wheel_mass <<
734 " cornering_stiffness: " << Wheel.cornering_stiffness <<
735 " friction_force_multiplier: " << Wheel.friction_force_multiplier <<
736 " side_slip_modifier: " << Wheel.side_slip_modifier <<
737 " slip_threshold: " << Wheel.slip_threshold <<
738 " skid_threshold: " << Wheel.skid_threshold <<
739 " max_steer_angle: " << Wheel.max_steer_angle <<
740 " affected_by_steering: " << Wheel.affected_by_steering <<
741 " affected_by_brake: " << Wheel.affected_by_brake <<
742 " affected_by_handbrake: " << Wheel.affected_by_handbrake <<
743 " affected_by_engine: " << Wheel.affected_by_engine <<
744 " abs_enabled: " << Wheel.abs_enabled <<
745 " traction_control_enabled: " << Wheel.traction_control_enabled <<
746 " max_wheelspin_rotation: " << Wheel.max_wheelspin_rotation <<
747 " external_torque_combine_method: " << Wheel.external_torque_combine_method <<
748 " lateral_slip_graph: " << FormatCurveLike(Wheel.lateral_slip_graph) <<
749 " suspension_axis: " << FormatVectorLike(Wheel.suspension_axis) <<
750 " suspension_force_offset: " << FormatVectorLike(Wheel.suspension_force_offset) <<
751 " suspension_max_raise: " << Wheel.suspension_max_raise <<
752 " suspension_max_drop: " << Wheel.suspension_max_drop <<
753 " suspension_damping_ratio: " << Wheel.suspension_damping_ratio <<
754 " wheel_load_ratio: " << Wheel.wheel_load_ratio <<
755 " spring_rate: " << Wheel.spring_rate <<
756 " spring_preload: " << Wheel.spring_preload <<
757 " suspension_smoothing: " << Wheel.suspension_smoothing <<
758 " rollbar_scaling: " << Wheel.rollbar_scaling <<
759 " sweep_shape: " << Wheel.sweep_shape <<
760 " sweep_type: " << Wheel.sweep_type <<
761 " max_brake_torque: " << Wheel.max_brake_torque <<
762 " max_hand_brake_torque: " << Wheel.max_hand_brake_torque <<
763 " wheel_index: " << Wheel.wheel_index <<
764 " location: " << FormatVectorLike(Wheel.location) <<
765 " old_location: " << FormatVectorLike(Wheel.old_location) <<
766 " velocity: " << FormatVectorLike(Wheel.velocity);
767 ++Index;
768 }
769 Info << std::endl;
770 }
771 }
772 else
773 SkipPacket();
774 break;
775
776 case static_cast<char>(CarlaRecorderPacketId::TrafficLightTime):
777 if (bShowAll)
778 {
779 ReadValue<uint16_t>(File, Total);
780 if (Total > 0 && !bFramePrinted)
781 {
782 PrintFrame(Info);
783 bFramePrinted = true;
784 }
785
786 Info << " Traffic Light time events: " << Total << std::endl;
787 for (i = 0; i < Total; ++i)
788 {
790 Info << " Id: " << TrafficLightTime.DatabaseId
791 << " green_time: " << TrafficLightTime.GreenTime
792 << " yellow_time: " << TrafficLightTime.YellowTime
793 << " red_time: " << TrafficLightTime.RedTime
794 << std::endl;
795 }
796 }
797 else
798 SkipPacket();
799 break;
800
801 case static_cast<char>(CarlaRecorderPacketId::WalkerBones):
802 if (bShowAll)
803 {
804 ReadValue<uint16_t>(File, Total);
805 if (Total > 0 && !bFramePrinted)
806 {
807 PrintFrame(Info);
808 bFramePrinted = true;
809 }
810
811 Info << " Walkers Bones: " << Total << std::endl;
812 for (i = 0; i < Total; ++i)
813 {
816 Info << " Id: " << WalkerBones.DatabaseId << "\n";
817 for (const auto& Bone : WalkerBones.Bones)
818 {
819 Info << " Bone: \"" << TCHAR_TO_UTF8(*Bone.Name) << "\" relative: " << "Loc("
820 << Bone.Location.X << ", " << Bone.Location.Y << ", " << Bone.Location.Z << ") Rot("
821 << Bone.Rotation.X << ", " << Bone.Rotation.Y << ", " << Bone.Rotation.Z << ")\n";
822 }
823 }
824 }
825 else
826 SkipPacket();
827 break;
828
829 // frame end
830 case static_cast<char>(CarlaRecorderPacketId::FrameEnd):
831 Info << std::endl;
832 break;
833
834 default:
835 SkipPacket();
836 break;
837 }
838 }
839
840 Info << "\nFrames: " << Frame.Id << "\n";
841 Info << "Duration: " << Frame.Elapsed << " seconds\n";
842
843 File.close();
844
845 return Info.str();
846}
847
848std::string CarlaRecorderQuery::QueryCollisions(std::string Filename, char Category1, char Category2)
849{
850 std::stringstream Info;
851
852 // get the final path + filename
853 std::string Filename2 = GetRecorderFilename(Filename);
854
855 // try to open
856 File.open(Filename2, std::ios::binary);
857 if (!File.is_open())
858 {
859 Info << "File " << Filename2 << " not found on server\n";
860 return Info.str();
861 }
862
863 if (!CheckFileInfo(Info))
864 return Info.str();
865
866 // other, vehicle, walkers, trafficLight, hero, any
867 char Categories[] = { 'o', 'v', 'w', 't', 'h', 'a' };
868 uint16_t i, Total;
869 struct ReplayerActorInfo
870 {
871 uint8_t Type;
872 FString Id;
873 };
874 std::unordered_map<uint32_t, ReplayerActorInfo> Actors;
875 struct PairHash
876 {
877 std::size_t operator()(const std::pair<uint32_t, uint32_t>& P) const
878 {
879 std::size_t hash = P.first;
880 hash <<= 32;
881 hash += P.second;
882 return hash;
883 }
884 };
885 std::unordered_set<std::pair<uint32_t, uint32_t>, PairHash > oldCollisions, newCollisions;
886
887 // header
888 Info << std::setw(8) << "Time";
889 Info << " " << std::setw(6) << "Types";
890 Info << " " << std::setw(6) << std::right << "Id";
891 Info << " " << std::setw(35) << std::left << "Actor 1";
892 Info << " " << std::setw(6) << std::right << "Id";
893 Info << " " << std::setw(35) << std::left << "Actor 2";
894 Info << std::endl;
895
896 // parse only frames
897 while (File)
898 {
899
900 // get header
901 if (!ReadHeader())
902 {
903 break;
904 }
905
906 // check for a frame packet
907 switch (Header.Id)
908 {
909 // frame
910 case static_cast<char>(CarlaRecorderPacketId::FrameStart):
911 Frame.Read(File);
912 // exchange sets of collisions (to know when a collision is new or continue from previous frame)
913 oldCollisions = std::move(newCollisions);
914 newCollisions.clear();
915 break;
916
917 // events add
918 case static_cast<char>(CarlaRecorderPacketId::EventAdd):
919 ReadValue<uint16_t>(File, Total);
920 for (i = 0; i < Total; ++i)
921 {
922 // add
924 Actors[EventAdd.DatabaseId] = ReplayerActorInfo{ EventAdd.Type, EventAdd.Description.Id };
925 }
926 break;
927
928 // events del
929 case static_cast<char>(CarlaRecorderPacketId::EventDel):
930 ReadValue<uint16_t>(File, Total);
931 for (i = 0; i < Total; ++i)
932 {
934 Actors.erase(EventAdd.DatabaseId);
935 }
936 break;
937
938 // events parenting
939 case static_cast<char>(CarlaRecorderPacketId::EventParent):
940 SkipPacket();
941 break;
942
943 // collisions
944 case static_cast<char>(CarlaRecorderPacketId::Collision):
945 ReadValue<uint16_t>(File, Total);
946 for (i = 0; i < Total; ++i)
947 {
949
950 int Valid = 0;
951
952 // get categories for both actors
953 uint8_t Type1, Type2;
954 if (Collision.DatabaseId1 != uint32_t(-1))
955 Type1 = Categories[Actors[Collision.DatabaseId1].Type];
956 else
957 Type1 = 'o'; // other non-actor object
958
959 if (Collision.DatabaseId2 != uint32_t(-1))
960 Type2 = Categories[Actors[Collision.DatabaseId2].Type];
961 else
962 Type2 = 'o'; // other non-actor object
963
964 // filter actor 1
965 if (Category1 == 'a')
966 ++Valid;
967 else if (Category1 == Type1)
968 ++Valid;
969 else if (Category1 == 'h' && Collision.IsActor1Hero)
970 ++Valid;
971
972 // filter actor 2
973 if (Category2 == 'a')
974 ++Valid;
975 else if (Category2 == Type2)
976 ++Valid;
977 else if (Category2 == 'h' && Collision.IsActor2Hero)
978 ++Valid;
979
980 // only show if both actors has passed the filter
981 if (Valid == 2)
982 {
983 // check if we need to show as a starting collision or it is a continuation one
984 auto collisionPair = std::make_pair(Collision.DatabaseId1, Collision.DatabaseId2);
985 if (oldCollisions.count(collisionPair) == 0)
986 {
987 Info << std::setw(8) << std::setprecision(0) << std::right << std::fixed << Frame.Elapsed;
988 Info << " " << " " << Type1 << " " << Type2 << " ";
989 Info << " " << std::setw(6) << std::right << Collision.DatabaseId1;
990 Info << " " << std::setw(35) << std::left << TCHAR_TO_UTF8(*Actors[Collision.DatabaseId1].Id);
991 Info << " " << std::setw(6) << std::right << Collision.DatabaseId2;
992 Info << " " << std::setw(35) << std::left << TCHAR_TO_UTF8(*Actors[Collision.DatabaseId2].Id);
993 Info << std::endl;
994 }
995 // save current collision
996 newCollisions.insert(collisionPair);
997 }
998 }
999 break;
1000
1001 case static_cast<char>(CarlaRecorderPacketId::Position):
1002 SkipPacket();
1003 break;
1004
1005 case static_cast<char>(CarlaRecorderPacketId::State):
1006 SkipPacket();
1007 break;
1008
1009 // frame end
1010 case static_cast<char>(CarlaRecorderPacketId::FrameEnd):
1011 // do nothing, it is empty
1012 break;
1013
1014 default:
1015 SkipPacket();
1016 break;
1017 }
1018 }
1019
1020 Info << "\nFrames: " << Frame.Id << "\n";
1021 Info << "Duration: " << Frame.Elapsed << " seconds\n";
1022
1023 File.close();
1024
1025 return Info.str();
1026}
1027
1028std::string CarlaRecorderQuery::QueryBlocked(std::string Filename, double MinTime, double MinDistance)
1029{
1030 std::stringstream Info;
1031
1032 // get the final path + filename
1033 std::string Filename2 = GetRecorderFilename(Filename);
1034
1035 // try to open
1036 File.open(Filename2, std::ios::binary);
1037 if (!File.is_open())
1038 {
1039 Info << "File " << Filename2 << " not found on server\n";
1040 return Info.str();
1041 }
1042
1043 if (!CheckFileInfo(Info))
1044 return Info.str();
1045
1046 // other, vehicle, walkers, trafficLight, hero, any
1047 uint16_t i, Total;
1048 struct ReplayerActorInfo
1049 {
1050 uint8_t Type;
1051 FString Id;
1052 FVector LastPosition;
1053 double Time;
1054 double Duration;
1055 };
1056 std::unordered_map<uint32_t, ReplayerActorInfo> Actors;
1057 // to be able to sort the results by the duration of each actor (decreasing order)
1058 std::multimap<double, std::string, std::greater<double>> Results;
1059
1060 // header
1061 Info << std::setw(8) << "Time";
1062 Info << " " << std::setw(6) << "Id";
1063 Info << " " << std::setw(35) << std::left << "Actor";
1064 Info << " " << std::setw(10) << std::right << "Duration";
1065 Info << std::endl;
1066
1067 // parse only frames
1068 while (File)
1069 {
1070
1071 // get header
1072 if (!ReadHeader())
1073 {
1074 break;
1075 }
1076
1077 // check for a frame packet
1078 switch (Header.Id)
1079 {
1080 // frame
1081 case static_cast<char>(CarlaRecorderPacketId::FrameStart):
1082 Frame.Read(File);
1083 break;
1084
1085 // events add
1086 case static_cast<char>(CarlaRecorderPacketId::EventAdd):
1087 ReadValue<uint16_t>(File, Total);
1088 for (i = 0; i < Total; ++i)
1089 {
1090 // add
1092 Actors[EventAdd.DatabaseId] = ReplayerActorInfo{ EventAdd.Type, EventAdd.Description.Id, FVector(0, 0, 0), 0.0, 0.0 };
1093 }
1094 break;
1095
1096 // events del
1097 case static_cast<char>(CarlaRecorderPacketId::EventDel):
1098 ReadValue<uint16_t>(File, Total);
1099 for (i = 0; i < Total; ++i)
1100 {
1102 Actors.erase(EventAdd.DatabaseId);
1103 }
1104 break;
1105
1106 // events parenting
1107 case static_cast<char>(CarlaRecorderPacketId::EventParent):
1108 SkipPacket();
1109 break;
1110
1111 // collisions
1112 case static_cast<char>(CarlaRecorderPacketId::Collision):
1113 SkipPacket();
1114 break;
1115
1116 // positions
1117 case static_cast<char>(CarlaRecorderPacketId::Position):
1118 // read all positions
1119 ReadValue<uint16_t>(File, Total);
1120 for (i = 0; i < Total; ++i)
1121 {
1123 // check if actor moved less than a distance
1124 if (FVector::Distance(Actors[Position.DatabaseId].LastPosition, Position.Location) < MinDistance)
1125 {
1126 // actor stopped
1127 if (Actors[Position.DatabaseId].Duration == 0)
1128 Actors[Position.DatabaseId].Time = Frame.Elapsed;
1129 Actors[Position.DatabaseId].Duration += Frame.DurationThis;
1130 }
1131 else
1132 {
1133 // check to show info
1134 if (Actors[Position.DatabaseId].Duration >= MinTime)
1135 {
1136 std::stringstream Result;
1137 Result << std::setw(8) << std::setprecision(0) << std::fixed << Actors[Position.DatabaseId].Time;
1138 Result << " " << std::setw(6) << Position.DatabaseId;
1139 Result << " " << std::setw(35) << std::left << TCHAR_TO_UTF8(*Actors[Position.DatabaseId].Id);
1140 Result << " " << std::setw(10) << std::setprecision(0) << std::fixed << std::right << Actors[Position.DatabaseId].Duration;
1141 Result << std::endl;
1142 Results.insert(std::make_pair(Actors[Position.DatabaseId].Duration, Result.str()));
1143 }
1144 // actor moving
1145 Actors[Position.DatabaseId].Duration = 0;
1146 Actors[Position.DatabaseId].LastPosition = Position.Location;
1147 }
1148 }
1149 break;
1150
1151 // traffic light
1152 case static_cast<char>(CarlaRecorderPacketId::State):
1153 SkipPacket();
1154 break;
1155
1156 // frame end
1157 case static_cast<char>(CarlaRecorderPacketId::FrameEnd):
1158 // do nothing, it is empty
1159 break;
1160
1161 default:
1162 SkipPacket();
1163 break;
1164 }
1165 }
1166
1167 // show actors stopped that were not moving again
1168 for (auto& Actor : Actors)
1169 {
1170 // check to show info
1171 if (Actor.second.Duration >= MinTime)
1172 {
1173 std::stringstream Result;
1174 Result << std::setw(8) << std::setprecision(0) << std::fixed << Actor.second.Time;
1175 Result << " " << std::setw(6) << Actor.first;
1176 Result << " " << std::setw(35) << std::left << TCHAR_TO_UTF8(*Actor.second.Id);
1177 Result << " " << std::setw(10) << std::setprecision(0) << std::fixed << std::right << Actor.second.Duration;
1178 Result << std::endl;
1179 Results.insert(std::make_pair(Actor.second.Duration, Result.str()));
1180 }
1181 }
1182
1183 // show the result
1184 for (auto& Result : Results)
1185 {
1186 Info << Result.second;
1187 }
1188
1189 Info << "\nFrames: " << Frame.Id << "\n";
1190 Info << "Duration: " << Frame.Elapsed << " seconds\n";
1191
1192 File.close();
1193
1194 return Info.str();
1195}
float y
float x
float z
std::string GetRecorderFilename(std::string Filename)
static std::string FormatVectorLike(V &&v)
static std::string FormatCurveLike(V &&v)
EVehicleDoor
Type of door to open/close.
geom::Point point
Definition LaneGraph.cpp:41
CarlaRecorderCollision Collision
CarlaRecorderAnimWalker Walker
CarlaRecorderEventParent EventParent
CarlaRecorderActorBoundingBox ActorBoundingBox
CarlaRecorderFrame Frame
CarlaRecorderEventDel EventDel
CarlaRecorderDoorVehicle DoorVehicle
CarlaRecorderAnimBiker Biker
CarlaRecorderVisualTime VisualTime
CarlaRecorderLightVehicle LightVehicle
CarlaRecorderAnimWheels VehicleWheels
CarlaRecorderStateTrafficLight StateTraffic
CarlaRecorderPhysicsControl PhysicsControl
bool CheckFileInfo(std::stringstream &Info)
CarlaRecorderLightScene LightScene
std::string QueryBlocked(std::string Filename, double MinTime=30, double MinDistance=10)
std::string QueryCollisions(std::string Filename, char Category1='a', char Category2='a')
CarlaRecorderWalkerBones WalkerBones
CarlaRecorderKinematics Kinematics
CarlaRecorderAnimVehicle Vehicle
CarlaRecorderWeather Weather
CarlaRecorderEventAdd EventAdd
CarlaRecorderPlatformTime PlatformTime
CarlaRecorderTrafficLightTime TrafficLightTime
CarlaRecorderPosition Position
CarlaRecorderInfo RecInfo
std::string QueryInfo(std::string Filename, bool bShowAll=false)
Defines the physical appearance of a vehicle whitch is obtained by the sensors.
std::vector< CarlaRecorderActorAttribute > Attributes
void Read(std::istream &InFile)
void Read(std::istream &InFile)
void Read(std::istream &InFile)
void Read(std::istream &InFile)
void Read(std::istream &InFile)
void Read(std::istream &InFile)
CarlaRecorderActorDescription Description
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)
FVehiclePhysicsControl VehiclePhysicsControl
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)
std::vector< CarlaRecorderWalkerBone > Bones
void Read(std::istream &InFile)
static VehiclePhysicsControl FromFVehiclePhysicsControl(const FVehiclePhysicsControl &Control)