24 template <
typename Packet>
25 bool RoundTrip(
const Packet &sent, Packet &got) {
26 std::ostringstream out;
28 const std::string bytes = out.str();
29 if (
static_cast<uint8_t
>(bytes[0]) != Packet::kPacketId) {
33 std::memcpy(&size, bytes.data() + 1,
sizeof(size));
35 return got.Read(in, size);
40TEST(MultiGpuWorldState, globals_round_trip) {
49 ASSERT_TRUE(RoundTrip(sent, got));
58TEST(MultiGpuWorldState, objects_round_trip) {
62 ASSERT_TRUE(RoundTrip(sent, got));
67TEST(MultiGpuWorldState, an_empty_set_is_not_an_absent_one) {
72 ASSERT_TRUE(RoundTrip(sent, got));
81TEST(MultiGpuWorldState, objects_with_an_unknown_field_keep_the_set) {
82 std::ostringstream payload;
84 std::ostringstream ids;
85 const uint32_t count = 1u;
86 const uint64_t
id = 42u;
87 ids.write(
reinterpret_cast<const char *
>(&count),
sizeof(count));
88 ids.write(
reinterpret_cast<const char *
>(&
id),
sizeof(
id));
90 const std::string body = payload.str();
91 std::istringstream in(body);
93 ASSERT_TRUE(got.
Read(in,
static_cast<uint32_t
>(body.size())));
98TEST(MultiGpuWorldState, an_impossible_object_count_fails) {
99 std::ostringstream payload;
100 std::ostringstream ids;
101 const uint32_t count = 1000000u;
102 ids.write(
reinterpret_cast<const char *
>(&count),
sizeof(count));
104 const std::string body = payload.str();
105 std::istringstream in(body);
107 EXPECT_FALSE(got.
Read(in,
static_cast<uint32_t
>(body.size())));
110TEST(MultiGpuWorldState, appearance_round_trip) {
114 prop.
scale = std::array<double, 3>{2.0, 2.0, 0.5};
119 sent.
actors = {prop, hidden};
121 ASSERT_TRUE(RoundTrip(sent, got));
122 ASSERT_EQ(got.
actors.size(), 2u);
124 EXPECT_EQ(got.
actors[0].collisions, std::optional<bool>(
false));
125 EXPECT_FALSE(got.
actors[0].hidden.has_value());
126 EXPECT_EQ(got.
actors[1].hidden, std::optional<bool>(
true));
129TEST(MultiGpuWorldState, layer_diff) {
130 const auto diff = ComputeMapLayerDiff(0x00FFu, 0x0F0Fu);
131 EXPECT_EQ(diff.first, 0x0F00u);
132 EXPECT_EQ(diff.second, 0x00F0u);
133 EXPECT_EQ(ComputeMapLayerDiff(0x1234u, 0x1234u), (std::pair<uint16_t, uint16_t>{0u, 0u}));
136TEST(MultiGpuWorldState, diff_sorted_ids) {
137 const auto diff = DiffSortedIds({1u, 3u, 5u}, {3u, 4u, 5u, 6u});
138 EXPECT_EQ(diff.first, (std::vector<uint64_t>{4u, 6u}));
139 EXPECT_EQ(diff.second, (std::vector<uint64_t>{1u}));
constexpr std::size_t kFrameDataHeaderSize
Frame data (the SEND_FRAME payload) is a sequence of packets [uint8 id][uint32 payload size][payload]...
void WriteField(std::ostream &out, uint8_t kind, const std::string &value)
std::pair< std::vector< uint64_t >, std::vector< uint64_t > > DiffSortedIds(const std::vector< uint64_t > ¤t, const std::vector< uint64_t > &desired)
Ids in desired and not in current (first), and the other way round (second).
std::pair< uint16_t, uint16_t > ComputeMapLayerDiff(uint16_t current, uint16_t desired)
The map layers to load and to unload to go from current to desired.
An actor's appearance on the primary that a mirror does not get from its spawn attributes or pose.
std::optional< bool > hidden
std::optional< std::array< double, 3 > > scale
std::optional< bool > collisions
Frame data packet 30, on change and on every full resync.
std::vector< ActorAppearance > actors
Frame data packet 28, on every frame: world-wide state a client can change on the primary that change...
float imu_gravity
The IMU's gravity, m/s^2.
bool publish_tf
ROS 2: whether TF frames are published.
uint16_t map_layers
rpc::MapLayer bits of the layers loaded.
bool day_night_cycle
UCarlaLightSubsystem: whether street lights follow the sun, and the last day/night state it broadcast...
Frame data packet 29, on change and on every full resync: map objects whose state is not part of any ...
bool Read(std::istream &in, uint32_t size)
void Write(std::ostream &out) const
@ kDisabledEnvironmentObjects
The complete, sorted set of environment objects disabled.
std::optional< std::vector< uint64_t > > disabled_environment_objects
TEST(MultiGpuWorldState, globals_round_trip)