Skip to content

Spherical harmonics reading reference radius from file - #1633

Open
carlo98 wants to merge 3 commits into
AVSLab:developfrom
carlo98:hotfix/bsk-1631-spherical_harmonics_radEq_mu
Open

carlo98 wants to merge 3 commits into
AVSLab:developfrom
carlo98:hotfix/bsk-1631-spherical_harmonics_radEq_mu

Conversation

@carlo98

@carlo98 carlo98 commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Description

GravBodyData.useSphericalHarmonicsGravityModel(file, maxDeg) loads spherHarm.radEquator and spherHarm.muBody from the first row of the coefficient file, but SphericalHarmonicsGravityModel::initializeParameters(const GravBodyData&) replaced both with the radEquator and mu of the gravity body, without a warning.

Normalized coefficients are only valid with the reference radius of their model. When the radii differ, every term of degree n is scaled by (R_body / R_file)^n.

Changes:

  • SphericalHarmonicsGravityModel::initializeParameters(const GravBodyData&) keeps the model radEquator when it is positive (loaded from the file or set by the user). body.radEquator is used only when the model has no radius, for example when the coefficients are set directly.
  • The field still uses body.mu, which keeps it consistent with the rest of the simulation. If body.mu is not positive, the model keeps its own muBody instead of producing a zero field. A mismatch between body.mu and the GM of the file is documented.
  • The factory body radii are unchanged, since radEquator of the body is also used by other modules.

Important: Scripts that set planet.radEquator to change the field must now set planet.spherHarm.radEquator.

Verification

  • Added three tests in src/simulation/dynamics/gravityEffector/_UnitTest/test_gravity_model_configuration.py.
  • Existing tests pass unchanged.

Documentation

  • Doxygen of SphericalHarmonicsGravityModel::initializeParameters and of the GravBodyData mu/radEquator members describes the behaviour.
  • Docstrings of useSphericalHarmonicsGravityModel (gravityEffector.i) and loadFromFile (sphericalHarmonicsGravityModel.i).
  • New section in gravityEffector.rst.
  • Release note snippet and an entry in bskKnownIssues.rst.

Future work

  • Consider an optional warning (or a user setting) when body.mu differs from the GM of the coefficient file.
  • scenarioGroundDownlink.py and scenarioSmallBodyNavUKF.py load spherical harmonics files but have no test in src/tests.

@carlo98
carlo98 requested a review from a team as a code owner October 19, 2026 09:39
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-19T09:40:44.550693Z f7d15f5 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@schaubh schaubh self-assigned this Oct 19, 2026
@schaubh schaubh added documentation Improvements or additions to documentation enhancement New feature or request labels Oct 19, 2026
@schaubh schaubh added this to Basilisk Oct 19, 2026

@schaubh schaubh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original reference-radius issue is valid, and retaining the coefficient model's radius while leaving the body's physical radius unchanged is the right fix. A compiled comparison of the original and proposed implementations against an independent J2 calculation confirmed the correction.

Requesting changes for the new GM fallback, which can make translational gravity and gravity-gradient torque use different gravitational parameters. There is also a smaller Doxygen documentation requirement to address; both findings are attached inline.

Validation: rebuilt the affected native target; all 31 gravity-effector tests passed; both touched headers compiled independently. An additional integrated spacecraft reproduction exposed the GM inconsistency described below.

Comment on lines +89 to +93
// The body gravitational parameter is used for the field so that it is consistent with
// the rest of the simulation (e.g. orbital element conversions).
if (body.mu > 0.0) {
this->muBody = body.mu;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Keep the effective GM consistent across gravity consumers

When body.mu remains at its default zero, this new fallback preserves the file GM only in spherHarm.muBody. GravityEffector::computeGravityField() still publishes body.mu as the planet's .mu state-engine property, which GravityGradientEffector uses. The result is nonzero orbital acceleration but zero gravity-gradient torque.

I reproduced this with a spacecraft using GGM03S truncated to degree zero, position [4.0e6, -3.0e6, 5.5e6] m, identity attitude, and inertia diag([500, 800, 350]) kgm^2. With body.mu = 0, the model GM is 3.986004415e14 m^3/s^2 and the published GM is zero; torque is [0, 0, 0]. Setting body.mu to the file GM leaves acceleration unchanged but gives torque [3.91313456072929e-4, 1.7391709158796851e-4, -1.8972773627778374e-4] Nm.

Please synchronize the effective GM across consumers, or require a positive body GM instead of accepting this partial fallback. Add an integrated regression test: the new test_spherical_harmonics_keep_file_mu_without_body_mu only checks the model's GM and therefore endorses the inconsistent configuration.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pushed a fix, @carlo98 , please see if you agree.

Comment on lines +45 to +51
* The attribute `radEquator` is kept if it is positive, for example when it was
* loaded from the coefficient file, since the normalized coefficients are only
* valid with the reference radius of their model. Otherwise, it is read from
* the `radEquator` of the given `GravBodyData`.
*
* The attribute `muBody` is replaced by the `mu` of the given `GravBodyData`
* if that value is positive. Otherwise, the current `muBody` is kept.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Add the required Doxygen parameter and return sections

This materially updated API comment falls under AGENTS.md's documentation requirement, but the overload still declares an unnamed const GravBodyData& parameter and provides no @param or @return sections. Generating Doxygen XML for this header confirms that neither section is present for this overload.

Please name the declaration parameter body and add @brief, @param body, and @return documentation, retaining the explanation of radius/GM precedence and the optional initialization error.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pushed a commit to address this.

- Require finite, positive body GM for spherical harmonics.
- Verify acceleration and gravity-gradient torque against GM saved before initialization.
- Align integrator SWIG vector declarations with shared bindings.
- Add import-order regression tests and update documentation.

Validation: 117 gravity, MuJoCo, binding, and integrator tests passed.

@carlo98 carlo98 left a comment •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@schaubh I agree with your previous commit, thank you. I left a few comments that are all linked together.

// Match swig_common_model.i's template arguments, including the inner allocator,
// so SWIG uses the same type descriptors for DoubleVector and MultiArray.
%template() std::vector<double, std::allocator<double>>;
%template() std::vector<std::vector<double, std::allocator<double>>>;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the same change be applied also in sphericalHarmonicsGravityModel.i? Adding it also to the relevant unittests?


@pytest.mark.parametrize("import_order", [
("gravityEffector", "svIntegrators"),
("svIntegrators", "gravityEffector"),

@carlo98 carlo98 Oct 20, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the comment "Should the same change be applied also in sphericalHarmonicsGravityModel.i?" is ok, then the following lines are needed here
("sphericalHarmonicsGravityModel", "svIntegrators"), ("svIntegrators", "sphericalHarmonicsGravityModel"),

nodes = [0.0, 0.5] # [-]

def coefficients():
model = gravityEffector.SphericalHarmonics()

@carlo98 carlo98 Oct 20, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the comment "Should the same change be applied also in sphericalHarmonicsGravityModel.i?" is ok, then the following line is needed here
for model in (gravityEffector.SphericalHarmonics(), SphericalHarmonicsGravityModel()):

importlib.import_module("Basilisk.simulation." + name)

from Basilisk.architecture import swig_common_model
from Basilisk.simulation import gravityEffector, spacecraft, svIntegrators

@carlo98 carlo98 Oct 20, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the comment "Should the same change be applied also in sphericalHarmonicsGravityModel.i?" is ok, then the following line should be added here
from Basilisk.simulation.sphericalHarmonicsGravityModel import SphericalHarmonicsGravityModel

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

Spherical harmonics use the body radEquator instead of the reference radius of the coefficient file

2 participants