Enh/tank geometry fluid density#72
Draft
aasitvora99 wants to merge 12 commits intomasterfrom
Draft
Conversation
Exposes structured drawing geometry that mirrors rocketpy.Rocket.draw(), so clients can redraw a rocket using the same shape math rocketpy uses without server-side rendering or duplicated geometry logic in the UI. Response carries per-surface shape_x/shape_y arrays, body tube segments, motor patch polygons (nozzle, chamber, grains, tanks, outline), rail button positions, sensors, t=0 CG/CP, and drawing bounds. Coordinates are already transformed into the draw frame rocketpy uses. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Align MotorModel and MotorTank with RocketPy's actual constructor requirements so invalid motors are rejected at the API boundary with a clear error rather than crashing deep inside RocketPy at simulate time. - MotorModel.validate_dry_inertia_for_kind: SOLID / LIQUID / HYBRID motors in RocketPy require dry_inertia with no default. Only GenericMotor accepts (0, 0, 0). Reject the default tuple for every kind except GENERIC with a message the user can act on. - MotorTank.discretize: change to Optional[int] = 100 to match the RocketPy Tank classes' default. Forms can now omit the field and still submit successfully. - stub_motor_dump fixture: use dry_inertia=[0.1, 0.1, 0.1] so tests that override motor_kind to SOLID / LIQUID / HYBRID still pass the new validator without each having to add a dry_inertia override locally.
RocketPy's rocket.draw() does not draw a combustion chamber for GenericMotor because _MotorPlots._generate_combustion_chamber reads grain-only attributes (grain_initial_height, grain_outer_radius, etc.) that GenericMotor lacks — it only emits a nozzle. Users who populate chamber_radius / chamber_height / chamber_position then saw no chamber in the jarvis playground. Add a GenericMotor branch in RocketService._build_motor_geometry that constructs an equivalent rectangular chamber patch from the chamber_* fields. Vertex ordering mirrors _generate_combustion_chamber so the patch flows through _generate_motor_region for outline assembly the same way a SolidMotor chamber does. Patch is emitted with role='chamber', flowing through the existing drawingMotorSchema + GeometryRocket renderer without frontend changes.
…nh/rocket-drawing-geometry
…eneric kinds Two related fixes surfaced during jarvis form refactor. 1. MotorModel.burn_time: float → Optional[float] = None. RocketPy's LiquidMotor / HybridMotor / SolidMotor all auto-detect burn_time from the thrust_source array span — forcing clients to supply it was wrong. GenericMotor still requires it; the service now raises a 422 at the API boundary when the GENERIC path receives None, instead of letting rocketpy error deeper in construction. 2. MotorService.from_motor_model: nozzle_position previously landed in motor_core only for the GenericMotor branch; Liquid / Hybrid / Solid silently ignored the user's value and took rocketpy's default of 0. Now forwarded via motor_core for every kind (conditionally, so a null still falls back to rocketpy's default). Removed the redundant nozzle_position kwarg on the GenericMotor constructor call. 3. Optional-forwarding convention: motor_core only carries burn_time / nozzle_position when the client actually supplied them, so rocketpy picks its own default otherwise instead of receiving None for number-typed args. Verified against real rocketpy: - LIQUID, burn_time=None → LiquidMotor auto-detects burn window - LIQUID, burn_time=2.0 → LiquidMotor builds with explicit window - LIQUID, nozzle_position=0.3 → LiquidMotor.nozzle_position == 0.3 - LIQUID, nozzle_position=None → LiquidMotor.nozzle_position == 0 - GENERIC, burn_time=None → 422 'burn_time is required for generic motors.' All 173 unit tests pass.
… guard Paired API-side work for the jarvis tank/fluid migration (branch feat/tank-fluid-schema-migration in jarvis-ts). Mirrors what that repo now sends on the wire: Schema (src/models/sub/tanks.py): - MotorTank.geometry is a discriminated union on geometry_kind: * custom → legacy piecewise (TankGeometry) * cylindrical → CylindricalTank(radius, height, spherical_caps) * spherical → SphericalTank(radius) - TankFluids.density accepts float or List[(T_K, rho)] temperature samples; pressure dependence deferred. - New validate_tank_kind_fields model_validator mirrors the validate_dry_inertia_for_kind pattern from motor.py — rejects payloads whose tank_kind omits required kind-specific fields at the API boundary with a kind-named 422 instead of letting rocketpy crash deeper in construction. - discretize is now optional (defaults to 100). Service (src/services/motor.py): - _build_rocketpy_tank_geometry dispatches on geometry_kind to TankGeometry/CylindricalTank/SphericalTank. - _build_rocketpy_fluid instantiates a real rocketpy.Fluid and wraps sampled density in a 1D Function-of-temperature callable; scalars pass through. (Eliminates the duck-typed Pydantic-into-rocketpy pattern that worked by accident.) Inverse path (src/services/flight.py): - _extract_fluid_density collapses Function-valued density back to a scalar at rocketpy's reference state (273.15 K, 101325 Pa) — lossy round-trip is documented; samples-roundtrip not supported in this iteration. - Geometry inverse always emits the 'custom' segment list shape; all three rocketpy geometry subclasses expose a piecewise .geometry dict so one code path covers them uniformly. Tests: - test_motors_route.py: 8 new cases covering each geometry_kind, sampled density, invalid discriminator, and all four tank_kind guard paths (MASS / MASS_FLOW / LEVEL / ULLAGE missing sub-fields). - tests/unit/test_services/test_motor_service.py: new suite exercising the adapter end-to-end against real rocketpy for each geometry×variant combination plus sampled density roundtrip. Routes (src/routes/motor.py): - POST /motors docstring gained an example payload showing the discriminated geometry union and sampled density shape. Gitignore: - Added .context and .pylint.d/ to keep local tooling artifacts out of the tree. Full suite: 173/173 pass.
Contributor
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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.
No description provided.