Reproduction case:
from numpy import degrees
from orbital import Position, Velocity, KeplerianElements, earth
R = Position(0, -2500000, 0)
V = Velocity(16703.9010129, 0, 0)
orbit = KeplerianElements.from_state_vector(R, V, body=earth)
print('arg_pe = %f°' % degrees(orbit.arg_pe))
r = orbit.r
v = orbit.v
print('r = (%f, %f, %f)' % (r.x, r.y, r.z))
print('v = (%f, %f, %f)' % (v.x, v.y, v.z))
The requirements are that the orbit is elliptical (non-circular), and flat (non-inclined), and the periapsis has a negative Y, so arg_pe is supposed to be > 180°. The above case is at the periapsis, which is (0, -2500000, 0).
Expected output:
arg_pe = 270.000000°
r = (0.000000, -2500000.000000, 0.000000)
v = (16703.901013, 0.000000, 0.000000)
Actual output:
arg_pe = 90.000000°
r = (0.000000, 2500000.000000, 0.000000)
v = (-16703.901013, 0.000000, 0.000000)
(Note that arg_pe is off by 180°, and both r and v are negated as a result.)
Analysis:
In utilities.elements_from_state_vector in the i ~= 0 and e ~= 0 case, there is a line:
arg_pe = acos(ev.x / norm(ev))
The use of acos means it's only ever going to return a value in range 0 to 180°, which will be wrong if ev.y is negative. This should be explicitly fixed up if ev.y is negative. I am working on a PR for this and other bugs relating to from_state_vector.
Reproduction case:
The requirements are that the orbit is elliptical (non-circular), and flat (non-inclined), and the periapsis has a negative Y, so
arg_peis supposed to be > 180°. The above case is at the periapsis, which is (0, -2500000, 0).Expected output:
Actual output:
(Note that
arg_peis off by 180°, and bothrandvare negated as a result.)Analysis:
In
utilities.elements_from_state_vectorin the i ~= 0 and e ~= 0 case, there is a line:The use of
acosmeans it's only ever going to return a value in range 0 to 180°, which will be wrong ifev.yis negative. This should be explicitly fixed up ifev.yis negative. I am working on a PR for this and other bugs relating tofrom_state_vector.