Skip to content

BUG: draw each declared eccentricity once per simulation - #1168

Merged
Gui-FernandesBR merged 1 commit into
RocketPy-Team:developfrom
thc1006:bug/stop-drawing-eccentricities-twice
Aug 15, 2026
Merged

BUG: draw each declared eccentricity once per simulation#1168
Gui-FernandesBR merged 1 commit into
RocketPy-Team:developfrom
thc1006:bug/stop-drawing-eccentricities-twice

Conversation

@thc1006

@thc1006 thc1006 commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Pull request type

  • Code changes (bugfix, features)

Checklist

  • Tests for the changes have been added (if needed)
  • Lint (ruff check / ruff format) has passed locally
  • All tests (pytest tests -m slow --runslow) have passed locally, apart from the pre-existing failures listed below
  • CHANGELOG.md: no action needed, an LLM workflow auto-updates it after merge

Current behavior

The follow-up @Gui-FernandesBR asked for in #1167 (comment).

#1167 declared the eccentricities that add_cp_eccentricity and add_thrust_eccentricity install, so dict_generator now draws them. create_object then calls _create_eccentricities, which draws them a second time and overwrites the first value in last_rnd_dict.

The exported inputs still match the applied ones, because the second write wins. What the extra draw costs is stream position. _create_eccentricities runs before the motor, surface and rail button loops, so every component position create_object places after it moves too.

Nose cone position, stochastic_calisto, seed 42:

develop this PR
no eccentricity 1.133146956072 1.133146956072
two declared 1.135127241207 1.134777791935
four declared 1.133041117399 1.135127241207

Four declared on this branch lands on two declared on develop, bit for bit, and so do the motor and lower rail button positions. Both consume four extra draws ahead of the component loops, which is the whole of the effect.

New behavior

_create_eccentricities reads a half that dict_generator has drawn already, and draws only a half the caller left out.

That second case is the reason this is not a plain dictionary lookup. add_cp_eccentricity(x=...) with no y is documented and supported, and y is then not a declared input, so it never reaches dict_generator. Reading the dictionary unconditionally raises KeyError on that call and drops cp_eccentricity_y from the exported inputs, which develop reports today. test_an_eccentricity_half_that_was_left_out_is_still_drawn holds that shut.

The docstring correction in test_an_eccentricity_added_after_init_is_still_drawn is the explanation from your #1167 review: the value did vary between simulations, what a fixed seed failed to do was reproduce it.

Breaking change

  • Yes

Fixed-seed baselines that declare an eccentricity move: the eccentricity values themselves, and every component position placed after them. Runs with no eccentricity are untouched, and so is anything drawn from a submodel's own generator. #1167 is not in a release yet and [Unreleased] already carries two entries that move fixed-seed baselines (#953 and #1102), so this folds into the same re-baseline rather than asking for a second one later.

Additional information

test_a_declared_eccentricity_is_not_drawn_a_second_time fails on unmodified develop, with all four values wrong. test_an_eccentricity_half_that_was_left_out_is_still_drawn passes there, and fails on the version that reads the dictionary unconditionally.

Local checks on 24861fdf, Linux, Python 3.13:

  • ruff check . and ruff format --check . clean, ruff 0.15.20
  • pylint rocketpy/ tests/ docs/ 10.00/10, exit 0
  • pytest tests/unit 2080 passed, pytest rocketpy --doctest-modules 48 passed, pytest tests/integration 153 passed, pytest tests/acceptance 18 passed
  • pytest tests -m slow --runslow 38 passed, 5 failed. The five are the EnvironmentAnalysis tests, and they fail the same way on an unmodified 24861fdf here. test_monte_carlo_simulate[True] also hangs on an unmodified 24861fdf on this machine, in a forked worker, so it is deselected from that count rather than reported as a pass.

RocketPy-Team#1167 declared the eccentricities that add_cp_eccentricity and
add_thrust_eccentricity install, so dict_generator draws them.
_create_eccentricities then drew them a second time and overwrote the first
value. The exported inputs matched the applied ones only because the second
write wins, and the extra draw moved every component position create_object
places after it.

Read what has been drawn already, and draw only a half the caller left out,
which is not a declared input and so never reaches dict_generator.

The docstring correction is the explanation RocketPy-Team#1167 landed with, which named
the wrong symptom: the value did vary between simulations, what a fixed seed
failed to do was reproduce it.

Signed-off-by: thc1006 <84045975+thc1006@users.noreply.github.com>
@thc1006
thc1006 requested a review from a team as a code owner August 15, 2026 15:55
@codecov

codecov Bot commented Aug 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.54%. Comparing base (24861fd) to head (52d6bc4).
⚠️ Report is 2 commits behind head on develop.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1168      +/-   ##
===========================================
+ Coverage    84.44%   84.54%   +0.09%     
===========================================
  Files          131      131              
  Lines        17491    17497       +6     
===========================================
+ Hits         14771    14792      +21     
+ Misses        2720     2705      -15     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Gui-FernandesBR
Gui-FernandesBR merged commit 74fc8ad into RocketPy-Team:develop Aug 15, 2026
10 checks passed
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.

2 participants