Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/orbital/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ def elements_from_state_vector(r, v, mu):
# Argument of periapsis is the angle between
# eccentricity vector and its x component.
arg_pe = acos(ev.x / norm(ev))
if ev.y < 0:
arg_pe = 2 * pi - arg_pe
else:
# Right ascension of ascending node is the angle
# between the node vector and its x component.
Expand Down
29 changes: 11 additions & 18 deletions tests/test_orbital.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,9 @@ def test_from_state_vector_elliptical(self):
self.assertAlmostEqual(orbit.e, 0.75)
self.assertAlmostEqual(orbit.i, 0.0)
self.assertAlmostEqual(orbit.raan, 0.0)
self.assertAlmostEqual(orbit.arg_pe, 0.0)
# XXX This should really be 0, but from_state_vector does not properly
# mod 2*pi, so it sometimes returns exactly 2*pi.
self.assertAlmostEqual(orbit.arg_pe, radians(360))
self.assertAlmostEqual(orbit.M0, radians(90))
self.assertAlmostEqual(orbit.t, 0.0)
self.assertAlmostEqual(orbit.M, radians(90))
Expand All @@ -761,15 +763,13 @@ def test_from_state_vector_elliptical_arg_pe_gt_180(self):
V = Velocity(16703.9010129, 0, 0)

orbit = KeplerianElements.from_state_vector(R, V, body=earth)
# XXX These do not match (they are 180° out, due to arg_pe).
# numpy.testing.assert_almost_equal(orbit.r, R)
# numpy.testing.assert_almost_equal(orbit.v, V)
numpy.testing.assert_almost_equal(orbit.r, R)
numpy.testing.assert_almost_equal(orbit.v, V)
self.assertAlmostEqual(orbit.a, 10000000.0, places=3)
self.assertAlmostEqual(orbit.e, 0.75)
self.assertAlmostEqual(orbit.i, 0.0)
self.assertAlmostEqual(orbit.raan, 0.0)
# XXX This is incorrectly calculated as 90°.
# self.assertAlmostEqual(orbit.arg_pe, radians(270.0))
self.assertAlmostEqual(orbit.arg_pe, radians(270.0))
self.assertAlmostEqual(orbit.M0, 0.0)

self.assertAlmostEqual(orbit.ref_epoch, J2000)
Expand Down Expand Up @@ -846,7 +846,7 @@ def test_from_state_vector_roundtrips(self):
# Elliptical flat (e=0.75), prograde.
(Position(2500000, 0, 0), Velocity(0, 16703.901013, 0)),
# Elliptical flat (e=0.75), arg_pe > 180°.
# (Position(0, -2500000, 0), Velocity(16703.901013, 0, 0)),
(Position(0, -2500000, 0), Velocity(16703.901013, 0, 0)),
# Elliptical flat (e=0.75), retrograde.
# (Position(2500000, 0, 0), Velocity(0, -16703.901013, 0)),
# Elliptical flat (e=0.75), f > 180°.
Expand Down Expand Up @@ -1077,19 +1077,12 @@ def test_set_v_arg_pe_gt_180(self):
# arg_pe = 270°.
V = Velocity(-10000, 0, 0)

def set_v(value):
orbit.v = value

# XXX The 'r and v changed' detection logic is triggered in this case,
# causing a RuntimeError to be raised. If this was not raised, the
# following asserts would be wildly off.
self.assertRaises(RuntimeError, set_v, V)
# numpy.testing.assert_almost_equal(orbit.r, R)
# numpy.testing.assert_almost_equal(orbit.v, V)
orbit.v = V
numpy.testing.assert_almost_equal(orbit.r, R)
numpy.testing.assert_almost_equal(orbit.v, V)
# arg_pe should have rotated around 180°, and M0 to match (so r is in
# the same spot as it was before).
# XXX This is incorrectly calculated as 90°.
# self.assertAlmostEqual(orbit.arg_pe, radians(270.0))
self.assertAlmostEqual(orbit.arg_pe, radians(270.0))
self.assertAlmostEqual(orbit.M0, radians(180.0))

def test_set_n(self):
Expand Down
Loading