fix(nav): [8/8] guard against null traffic light in WalkerManager - #9758
Merged
Blyron merged 7 commits intoJul 14, 2026
Merged
Conversation
JArmandoAnaya
force-pushed
the
fix/walker-manager-traffic-light-guard
branch
from
May 27, 2026 09:04
a94e30b to
7ee1a3d
Compare
This was referenced May 27, 2026
JArmandoAnaya
force-pushed
the
fix/walker-manager-traffic-light-guard
branch
from
May 27, 2026 09:42
7ee1a3d to
3d326ca
Compare
4 tasks
JArmandoAnaya
force-pushed
the
fix/walker-manager-traffic-light-guard
branch
3 times, most recently
from
May 27, 2026 20:07
593ecd3 to
c5676fb
Compare
9 tasks
JArmandoAnaya
force-pushed
the
fix/walker-manager-traffic-light-guard
branch
from
June 6, 2026 19:54
c5676fb to
e5fd8aa
Compare
…X, V2I) Port the V2X sensor family to ue5-dev: the CAM sensor (sensor.other.v2x) with ETSI CAM generation via CaService, the custom-payload sensor (sensor.other.v2x_custom) carrying a fixed binary blob, the PathLossModel propagation engine, and owner-less V2I (infrastructure) sensors. Adds the engine-agnostic LibCarla message model (LibITS ITS types, CAMData / CustomV2XData containers, V2X serializers, CustomV2XBytes RPC type), wires both sensors into the SensorRegistry, exposes the client send() RPC path, and adds the actor-definition builders, Python bindings, and docs. V2X is a client-streamed sensor: data flows sensor -> SensorRegistry serializer -> stream -> Python listen() callback. No DDS publisher is added here, matching upstream; the data model is the foundation a future ROS 2 publisher would consume. Plain C++ models (CaService, PathLossModel) are owned via std::unique_ptr so teardown frees them after UE clears ownership; the static actor maps are cleared in EndPlay so a destroyed sensor leaves no dangling AActor* key. CustomV2XBytes is zero-initialized. Coverage: GTest round-trip for the serializers and the binary blob; manual smoke test for CAM generation, custom send/receive, and V2I. Upstream subjects and bodies (verbatim): v2x 2nd try Extend ROS2 support Step 1: V2XSensor (carla-simulator#9435) - V2XSensor allows selection of virtual communication channels via sensors 'channel_id ' attribute. - V2XCustomSensor sends bytes instead of std::string to support binary data blobs - V2XCustomSensor allows multiple messages to be sent at once supporting individual larger messages - Allow V2X-sensors without an owner if these are placed within the infrastructure (V2I communication) - Removed the extra height on the PathLossModel after switching the actor to the sensor's actor instance. Therefore, the considered position is always the position of the sensor itself which can be defined when spawning/attaching - Updated V2X docu (adapted from ue4-dev c7cfdad, 8f33324) Co-Authored-By: Daniel Grimm <daniel.grimm@kit.edu> Co-Authored-By: berndgassmann <bernd.gassmann@motor-ai.com>
…ypes Address correctness and robustness issues in the V2X sensor family: - CaService: initialize mGenCamLowDynamicsLimit (and its counter) so the CAM low-dynamics fallback rate is deterministic instead of reading uninitialized memory; seed PrevLocation/PrevDeltaTime in the vehicle init path so the first acceleration estimate does not read uninitialized FVector components or divide by a zero delta time (mirrors AInertialMeasurementUnit, driving the first reading to ~0). - PathLossModel: make Frequency_GHz/Frequency/lambda per-instance fields. They were static, so two sensors configured with different frequencies clobbered each other globally and corrupted the path-loss math; clamp the propagation distance to the FSPL reference distance before any log10/division so co-located actors no longer feed -inf/NaN into the received-power computation. - CAM wire type: store PathPoint::pathDeltaTime inline with an availability flag instead of a raw pointer. The message is copied byte-for-byte onto the sensor data stream, so a server-side pointer must never travel on the wire. - V2X/CustomV2X sensors: skip senders with no queued message (front() on an empty list is undefined behaviour) and look up sender queues with find-or-skip instead of map::at, which would throw if a sender dropped out of the map between the simulate and retrieval passes. - Python set_bytes: size the copy from the buffer's byte length rather than its element count, so a buffer with itemsize > 1 (e.g. a NumPy int32 array) is copied in full. - Fix two user-visible/comment typos. Add unit coverage for the inline CAM path-delta-time wire type (value-not-pointer, trivially copyable, serializer round-trip) and a smoke test that exercises set_bytes with a multi-byte-itemsize buffer.
WalkerManager::GetAllTrafficLightWaypoints collected every traffic light affecting a pedestrian route by static_pointer_cast-ing each candidate to TrafficLight and dereferencing it without a null check, so an actor that reported the traffic-light type but did not resolve to a TrafficLight caused a null dereference. Iterate World::GetActors() (the same episode actor set), filter on the type id, dynamic_pointer_cast to TrafficLight and guard the result before reading its stop waypoints. Also drop the dead per-actor GetActorSnapshot query whose result was never used. Add a smoke test that drives a controller.ai.walker so the reworked gather and the AI routing path run end to end without taking the server down. From upstream "Extend ROS2 support Step 2: Serializer and RPC (carla-simulator#9449)": - nav/WalkerManager: prevent from using nullptr (adapted from ue4-dev 1146277) Co-Authored-By: berndgassmann <bernd.gassmann@motor-ai.com>
…s mode World::ApplySettings drove the fixed_delta_seconds settling loop with an unconditional Tick(), which sends a tick cue and synchronizes to that frame. In asynchronous mode the server free-runs and only waits on a client tick cue in synchronous mode (CarlaEngine's frame loop gates on bSynchronousMode), so the client should wait for the next server-produced frame rather than drive one. Call Tick() only in synchronous mode and WaitForTick() otherwise. Pair the SyncSmokeTest teardown to tick only when the restored settings keep synchronous mode active. From upstream "Extend ROS2 support Step 2: Fine grained ServerSynchronization (carla-simulator#9450)": - Ensure tick calls are ignored if sync mode is not active. - Client needs to wait for next tick on non synchronous mode (adapted from ue4-dev aa9c92b) Co-Authored-By: berndgassmann <bernd.gassmann@motor-ai.com>
Add a consolidated CHANGELOG entry for the ROS 2 enhancement port series: the publisher and subscriber template rework with an Ackermann control subscriber, the new geom velocity, acceleration and quaternion types with the pitch and roll rotation fix, the ROS2TopicVisibility startup flag, the V2X sensor family, the IMU compass yaw and actor disposal-order fix, and the pedestrian navigation null-dereference hardening.
Align the ue5-dev ROS 2 rviz launcher with ue4-dev. run_rviz.sh now builds a versioned Docker image from a local Dockerfile and accepts a --distro argument (humble or jazzy) instead of pulling a hardcoded osrf/ros:humble-desktop image, and the Dockerfile it builds from is added. This is the FastDDS-only slice of the upstream change; the CycloneDDS RMW selection (--rmw) and its cyclonedds.xml profile are deferred to a later change. The example vehicle stays vehicle.lincoln.mkz, as the ue4-dev mkz_2017 blueprint is not shipped here. Upstream commit: Update ROS2 Example (carla-simulator#9672) * Added `--distro` and `--rmw` arguments to `run_rviz.sh` to be able to run the example with ROS2 distros `Humble` and `Jazzy` and RMW `FastDDS` and `CycloneDDS` * add udp transport to cyclonedds config file (adapted from ue4-dev 7fd91eb) Co-Authored-By: Luis Poveda Cano <luispovedacano@gmail.com>
JArmandoAnaya
force-pushed
the
fix/walker-manager-traffic-light-guard
branch
from
July 7, 2026 05:44
e5fd8aa to
3d69aeb
Compare
JArmandoAnaya
marked this pull request as ready for review
July 13, 2026 09:09
Contributor
Author
|
Thank you for merging the previous PRs. Now this one is ready for review. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is the final PR (8 of 8) of the ROS 2 enhancement port from ue4-dev. It is stacked on #9757 and opened against
ue5-dev, so its diff includes the lower PRs in the chain until they merge. Its own changes are two small fixes plus the consolidated series CHANGELOG.WalkerManager::GetAllTrafficLightWaypointscast every candidate actor toTrafficLightand dereferenced it without a null check, so an actor that reported the traffic-light type but did not resolve to aTrafficLightcould null-dereference. It now iteratesWorld::GetActors(), filters on the type id, anddynamic_pointer_casts behind a null guard. Separately,World::ApplySettingsno longer callsTick()in asynchronous mode, where the server free-runs and only honors tick cues in synchronous mode; it waits for the next server frame instead.Changes
WalkerManageragainst a null or non-TrafficLightactor, and drop a dead per-actor snapshot query whose result was unused.test_walker_navigationsmoke test that drives acontroller.ai.walkerso the reworked gather and the AI routing path run end to end.World::ApplySettings: tick only in synchronous mode, wait for the server otherwise; pair the sync smoke-test teardown.Closes #9627
Where has this been tested?
libcarla_test_client154/154 andlibcarla_test_server140/140 pass;smoke.test_walker_navigationpasses against the Development package.Possible Drawbacks
World.apply_settingsin asynchronous mode now waits for a server frame rather than sending a tick cue during the settling loop. The observable result is unchanged, but the call path differs.Series status
Related: #9627, #9757
This change is