Skip to content

Setting E does not mod by 2pi, resulting in convergence errors #37

@mgiuca

Description

@mgiuca

Steps to reproduce:

Run the following program:

from numpy import degrees, radians
from orbital import earth, KeplerianElements

orbit = KeplerianElements(a=1000.0, e=0.75, body=earth)

orbit.E = radians(485.140095)
print('orbit.M = %f°' % degrees(orbit.M))
print('orbit.E = %f°' % degrees(orbit.E))

Expected behaviour:

(Ignoring the OrbitalWarning that is always printed when using the E setter.)

orbit.M = 90.000000°
orbit.E = 125.140095°

Actual behaviour:

orbit.M = 450.000000°
Traceback (most recent call last):
  File "set-e-error.py", line 8, in <module>
    print('orbit.E = %f°' % degrees(orbit.E))
                                    ^^^^^^^
  File "orbital/elements.py", line 200, in E
    return eccentric_anomaly_from_mean(self.e, self._M)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "orbital/utilities.py", line 99, in eccentric_anomaly_from_mean
    raise ConvergenceError('Did not converge after {n} iterations. (e={e!r}, M={M!r})'.format(n=MAX_ITERATIONS, e=e, M=M))
orbital.utilities.ConvergenceError: Did not converge after 100 iterations. (e=0.75, M=np.float64(7.853981640431436))

This is because the E setter (or utilities.mean_anomaly_from_eccentric) does not mod the resulting value of M by 2pi, so M is set to 450° instead of 90°, and then the E getter has unexpected behaviour when using the value of M outside the range. Note that the convergence error only occurs for sufficiently eccentric orbits (it does not crash when e=0.0).

Note that both the M and f setters do mod by 2pi, it is only the E setter that fails to do so.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions