Skip to content

fix: four paths that skipped a rule FIXS already states - #324

Open
yunlishao-vibe wants to merge 4 commits into
dev_v0.9.0from
fix/cosim_setup_gaps
Open

fix: four paths that skipped a rule FIXS already states#324
yunlishao-vibe wants to merge 4 commits into
dev_v0.9.0from
fix/cosim_setup_gaps

Conversation

@yunlishao-vibe

Copy link
Copy Markdown
Contributor

Four independent fixes, one commit each, all found while bringing a new
RoadRunner map (UGA campus) up on a source build. They share a shape: FIXS
states a rule, and one code path did not enforce it.

fix(#311) — the cook never got the editor flags

-DisableFrameTraceCapture reaches the three UE4Editor launches FIXS assembles
itself. The map cook is a fourth, and its argv belongs to CARLA's
Util/BuildTools/Import.py. Observed command line from a failed cook:

-run=ImportAssets -importSettings="..." -nosourcecontrol -replaceexisting

No flag. Fixed by setting UE-CmdLineArgs in the child environment, which UE4
appends to any command line it parses.

fix — per-user site-packages shadowed the configured env

carla.json names one interpreter; that does not settle which packages it
imports. A conda env has no pyvenv.cfg, so CPython puts the per-user site
directory ahead of the env's own site-packages, and one
pip install --user shadows an env-installed package in every env at once.

A 0.9.16 carla built from a source tree won over the 0.9.15 wheel the config
installed. CARLA only warns on a version gap, so the run connected to a
0.9.15.2 server and died on the first camera image inside libcarla —
ImageTmpl.h's GetWidth() * GetHeight() == size() assert, which takes the
process down rather than raising into python.

Exports PYTHONNOUSERSITE for children and drops the directory from this
process's sys.path. Done at import, so it also covers run_cosim --version,
which returns above the re-exec and was reporting the shadowed copy as
carla present.

fix — the TL table is in SUMO coordinates, so flip it by default

Measured across five cooked maps (uga, roosevelt, mlk ×2, atlanta): 1156
rows, not one negative y
. CARLA's world is left-handed, so SUMO (x, y) is
CARLA (x, -y). Without the flip the spectator went to +y where there is no
road — on UGA the busiest junction is at y=1200, so the camera framed a point
2400 m north of it and the map read as failed-to-load.

The flag is now tri-state, and an explicit CLI flag finally beats the per-map
setting. The old args.no_net_offset or settings.get("net_offset") == "zero"
meant the flip could never be turned off on a map recording "zero", despite
the comment above it promising the opposite. "zero" still means ON; a map
opts out with net_offset: "keep".

feat — checkpoint the setup before the map import

The setup is saved before the launch, but after the import — and the import
is what fails for reasons outside the script. A failed cook discarded the app,
map and local pick just chosen, and re-asked the whole questionnaire at exactly
the moment you want to change one answer and retry.

save_partial writes the answers early under the same name, tagged with the
stage that had not run; the full save clears the tag.

Verification

  • Each of the four commits compiles on its own (py_compile, all four files) —
    bisectable.
  • User-site: carla resolves from the user directory before and from the env's
    0.9.15 wheel after, and a child process inherits the change.
  • Net-offset: resolution matrix checked over {no flag, --no-net-offset,
    --net-offset} × {no setting, "zero", "keep"}.
  • RenderDoc: env var composes, appends rather than clobbers, and round-trips to
    a child on Windows.
  • Resume: checkpoint → picker surfaces it → retry clears the tag and leaves one
    entry, with a normal record never gaining the key.

Not yet exercised end to end in a live co-sim; each change was verified in
isolation.

… argv

-DisableFrameTraceCapture went into EDITOR_LAUNCH_FLAGS and reached the three
UE4Editor launches FIXS assembles itself - run_cosim, place_tls, place_signs.
The map cook is a fourth, and FIXS does not build its command line: it shells
out to CARLA's Util/BuildTools/Import.py, which assembles the ImportAssets
commandlet argv from its own list. So the flag never arrived there and the
"Locate main RenderDoc executable..." dialog still blocked a cook, the one
launch with no timeout at all.

UE4 appends whatever UE-CmdLineArgs holds to any command line it parses
(Engine/Source/Runtime/Core, LogSuppressionInterface.cpp:634), so setting it in
the child environment puts the flag into an argv owned by someone else without
patching their script. Appends rather than assigns, so an operator who already
uses the variable keeps what they set.
carla.json names one interpreter and every entry point re-execs under it, but
naming the interpreter does not settle which packages it imports. A conda env
has no pyvenv.cfg, so CPython leaves ENABLE_USER_SITE on and puts the per-user
site directory AHEAD of the env's own site-packages. One `pip install --user`
therefore shadows an env-installed package in every env on the machine at once.

Measured: a carla built from a 0.9.16 source tree landed in
%APPDATA%\Python\Python310\site-packages and won over the 0.9.15 wheel the
config had installed. The client connected to a 0.9.15.2 server, CARLA only
WARNED about the version gap and connected anyway, and the run died on the
first camera image inside libcarla - ImageTmpl.h's
GetWidth() * GetHeight() == size() assertion, a C++ assert, so it took the
process down instead of raising something python could report.

Two moves, because an env var cannot repair a process that has already booted:
export PYTHONNOUSERSITE so every child starts without the directory, and drop
it from this process's sys.path for the case where we are already on the
configured interpreter and so never re-exec. Done at import rather than from a
call each entry point must remember, because it has to beat `import carla` on
every path - including run_cosim --version, which returns above the re-exec and
would otherwise fingerprint the shadowed copy as "carla present", in the output
whose own help text calls it what to paste into a bug report.

The notice names the interpreter, not the directory that was dropped: which
python you got is the question a shadowed import makes unanswerable, and it is
the only part of this a reader can act on. It prints only on the paths that
return - a re-exec already names the python it switches to.
Every tl_table FIXS writes is in SUMO coordinates. Measured across five cooked
maps on one machine - uga, roosevelt, mlk (two vintages), atlanta: 1156 rows,
not one negative y. CARLA's world is left-handed, so a SUMO point (x, y) is
CARLA (x, -y), and _table_junctions already knows this - it just did the flip
only when --no-net-offset was passed.

Off was never right for a table FIXS generated. It is right only for a table
already written in CARLA coordinates, which is what the new --net-offset is
for. Without the flip the spectator is sent to +y where there is no road: on
the UGA campus map the busiest junction sits at y=1200, so the camera framed a
point 2400 m north of it and the map read as having failed to load - the same
symptom _frame_from_map was added to cure.

The flag is now tri-state so the per-map setting can still opt out, and an
explicit flag finally beats it. The old expression was

    args.no_net_offset or settings.get("net_offset") == "zero"

which meant that on a map recording "zero" the flip could not be turned off
from the command line at all, despite the comment two lines above promising
that explicit CLI flags override. "zero" keeps meaning ON, so existing per-map
settings carry over unchanged; a map opts out with net_offset: "keep".
The setup is saved before the LAUNCH, deliberately - a run that failed to start
is the one you want to come back to and tweak. But it is saved after the map
IMPORT, and the import is the step that fails for reasons outside this script:
a cook that crashes the editor, a bundle that will not open. A failed cook
therefore discarded the app, map and local pick just chosen, and the next run
asked the whole questionnaire again - at exactly the moment you want to change
one answer and retry.

save_partial writes the record as soon as the questionnaire's answers are
settled, tagged with the stage that had not run yet, under the same name - so
finishing later overwrites it instead of leaving a second entry behind, and the
full save clears the tag. config/config_scope are not checkpointed: they are
resolved after the import, and the record already carries what the previous run
knew, which is the right thing to come back to.

The stage is a name, not a flag, because it is shown in the picker: "map
import" reads as a thing to retry where a bare "incomplete" reads as
corruption. A headless run says it out loud, since it draws no list and
silently replaying a setup whose map never cooked is how the failure gets
rediscovered further downstream.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant