|
| 1 | +--- |
| 2 | +# Scout Report — 2023-10-24 |
| 3 | + |
| 4 | +## ✅ SELECTED ISSUE: 1 |
| 5 | +*(Fill in 1, 2, or 3 after reviewing the briefs below)* |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Issue 1 — BUG: Wind Heading Profile Plots are not that good (https://github.com/RocketPy-Team/RocketPy/issues/253) |
| 10 | + |
| 11 | +### What's broken |
| 12 | +When wind direction wraps around from 360° to 0°, the matplotlib plot draws a connecting line across the entire width of the graph. This creates a visually confusing plot that misrepresents the actual wind heading interpolation between those altitudes. The line should break or wrap around cleanly instead of crossing the plot. |
| 13 | + |
| 14 | +### Files to touch |
| 15 | +- `rocketpy/plots/environment_plots.py` |
| 16 | +- `tests/integration/environment/test_environment.py` |
| 17 | + |
| 18 | +### Implementation approach |
| 19 | +1. In `rocketpy/plots/environment_plots.py`, locate the `__wind` method where wind speed and direction are plotted. |
| 20 | +2. Extract the wind direction values into a numpy array: `directions = np.array([self.environment.wind_direction(i) for i in self.grid])`. |
| 21 | +3. Identify points where the absolute difference between consecutive values exceeds a threshold (e.g., 180°). |
| 22 | +4. Insert `np.nan` into both the `directions` array and the corresponding `grid` (altitude) array at these jump points to break the matplotlib line, or apply a masked array to hide the connecting segments. |
| 23 | +5. Update the `axup.plot()` call to use these modified arrays instead of the list comprehension. |
| 24 | + |
| 25 | +### Acceptance criteria |
| 26 | +- The wind direction plot no longer shows horizontal lines connecting 360° back to 0° across the graph. |
| 27 | +- The plotted data points remain accurate and are not shifted. |
| 28 | +- All existing environment tests still pass. |
| 29 | + |
| 30 | +### Guardrails |
| 31 | +- Do not modify the underlying `Environment` or `Function` classes or how wind heading is calculated mathematically. |
| 32 | +- Do not add new external dependencies to handle the plotting logic. |
| 33 | + |
| 34 | +### Difficulty |
| 35 | +2 — The issue is contained entirely within the plotting utility and relies on a standard matplotlib workaround for cyclic data. |
| 36 | + |
| 37 | +--- |
| 38 | + |
| 39 | +## Issue 2 — ENH: Save Monte Carlo outputs to .csv and .json formats (https://github.com/RocketPy-Team/RocketPy/issues/242) |
| 40 | + |
| 41 | +### What's broken |
| 42 | +Currently, the `MonteCarlo` class saves simulation outputs (results, inputs, and errors) primarily to `.txt` files. This makes post-processing difficult for users who want to analyze their data in external tools like Excel, MATLAB, or generic Python scripts without loading RocketPy. The user should be able to choose the output format easily to export their dispersion results. |
| 43 | + |
| 44 | +### Files to touch |
| 45 | +- `rocketpy/simulation/monte_carlo.py` |
| 46 | +- `tests/integration/simulation/test_monte_carlo.py` |
| 47 | + |
| 48 | +### Implementation approach |
| 49 | +1. In `rocketpy/simulation/monte_carlo.py`, add new methods to the `MonteCarlo` class: `export_results_to_csv(self, filename)` and `export_results_to_json(self, filename)`. |
| 50 | +2. Inside `export_results_to_csv`, use Python's built-in `csv` module to open the file and write headers (keys of `self.results`) and rows corresponding to each simulation iteration. |
| 51 | +3. Inside `export_results_to_json`, use Python's built-in `json` module to dump the `self.results` dictionary directly to the file. |
| 52 | +4. Optionally, create a unified `export_results(self, filename, format="csv")` method that calls the appropriate specific method based on the `format` argument. |
| 53 | +5. Ensure that custom `data_collector` variables are included in the export (they should already be in `self.results`). |
| 54 | + |
| 55 | +### Acceptance criteria |
| 56 | +- The `MonteCarlo` class has methods to export data to both `.csv` and `.json` formats. |
| 57 | +- The exported files contain the correct data stored in the `self.results` dictionary, structured appropriately. |
| 58 | +- Unit tests verify that the files are created and contain the expected data. |
| 59 | +- Built-in `csv` and `json` libraries are used without adding heavy dependencies like `pandas`. |
| 60 | + |
| 61 | +### Guardrails |
| 62 | +- Do not modify how the Monte Carlo simulation itself runs or how it generates `self.results`. |
| 63 | +- Avoid using heavy dependencies like `pandas`; stick to Python's built-in libraries. |
| 64 | + |
| 65 | +### Difficulty |
| 66 | +2 — Straightforward implementation using standard Python libraries, requiring basic dictionary and list manipulation to format the outputs correctly. |
| 67 | + |
| 68 | +--- |
| 69 | + |
| 70 | +## Issue 3 — ENH: Implement Parachute Opening Shock Force Estimation (https://github.com/RocketPy-Team/RocketPy/issues/161) |
| 71 | + |
| 72 | +### What's broken |
| 73 | +RocketPy currently cannot estimate the transient opening shock force that occurs when a parachute inflates. This leaves users unable to size their recovery hardware properly, as the steady-state drag force is significantly lower than the peak shock force. |
| 74 | + |
| 75 | +### Files to touch |
| 76 | +- `rocketpy/rocket/parachute.py` |
| 77 | +- `tests/fixtures/parachutes/parachute_fixtures.py` |
| 78 | + |
| 79 | +### Implementation approach |
| 80 | +1. Update the `Parachute.__init__` signature in `rocketpy/rocket/parachute.py` to accept an `opening_shock_coefficient` parameter, defaulting to a standard value like `1.5` or `1.6`. |
| 81 | +2. Store this parameter as an instance variable (`self.opening_shock_coefficient = opening_shock_coefficient`). |
| 82 | +3. Add a new method `calculate_opening_shock(self, density, velocity)` to the `Parachute` class. |
| 83 | +4. Implement the Knacke formula: `F_o = self.opening_shock_coefficient * 0.5 * density * velocity**2 * self.cd_s`. (Note: this assumes the infinite mass opening factor $X_1$ is combined with $C_x$ as mentioned in the issue). |
| 84 | +5. Return the calculated force $F_o$. |
| 85 | + |
| 86 | +### Acceptance criteria |
| 87 | +- The `Parachute` class accepts and stores `opening_shock_coefficient`. |
| 88 | +- The new `calculate_opening_shock` method correctly calculates the peak shock force based on the provided inputs and the parachute's $C_d S$. |
| 89 | +- A unit test verifies the calculation against a known manual calculation or textbook example. |
| 90 | + |
| 91 | +### Guardrails |
| 92 | +- Do not integrate this transient force into the main `Flight` equations of motion yet, as the issue requests it primarily for post-processing estimation. |
| 93 | +- Do not modify the existing steady-state drag calculations. |
| 94 | + |
| 95 | +### Difficulty |
| 96 | +1 — Requires adding a single instance variable and a straightforward mathematical method to an existing class, plus a basic unit test. |
| 97 | +--- |
0 commit comments