2

I have assignment and part of it involves getting a satellite to orbit both the Earth and the Moon at least once. How ever no matter how I set my initial condition or parameterize my position and time evolve it my satellite won't orbit the moon and comeback. Note both the Moon and Earth lie on the x axis the system is in their co-rotating frame, I am using a fourth order Runge Kutta to simulate the orbit.

Update 1: After some suggestion from the comments below my script to explain the problem a bit more when I run my code the satellite spirals out and does not orbit , I have also added a plot of the satellite

Update 2 : For those wondering where I got my acceleration term for the satellite and why it includes Coriolis and the Centrifugal force along with the gravitational force between satellite and Earth and Satellite and moon see this reference http://farside.ph.utexas.edu/teaching/336k/Newtonhtml/node123.html and chapter 7 of this http://farside.ph.utexas.edu/teaching/336k/Newton.pdf

Updated 3: Fixed an error in the position of the satellite, and a typo in the comments of the code,updated the image that corresponded to the correction in the code

from pylab import plot,show,xlabel,ylabel,cla,clf
from numpy import linspace,exp,sin,cos,zeros,array,pi ,exp



M2 = 5.972e24 # M Earth kg
M1 = 7.34767309e22 # M moon kg
G= 6.6742e-11
R=3.844e8 #m Earth-moon distance
R_e =6371e3 # Earth radius
R_m = 1737e3 # Moon radius
M_0 = ((M2 - M1)/(M2 + M1))
alpha = pi/3
omega_0 = ((G*(M2 + M1))/(R**3))**(1/2)
T_a = (2*pi)/omega_0 # System period

def dot_p(a,b):
    n= len(a)
    d=0
    for i in range(n):
        d = d+ a[i]*b[i]
    return d

def abs_v(x):
    return (dot_p(x,x))**(1/2)

r_1 = array([(M2*R)/(M2 + M1),0,0],float) # Position of Moon
r_2 = array([-(M1*R)/(M2 + M1),0,0],float) #Position of Earth
omega =  array([0,0,omega_0],float) #Angular velocity of Earth and Moon

def F(r,t):
    r1 = r[0,:] #Earth position
    vr1 = r[1,:] #Earth velocity
    r2 = r[2,:] #Moon position
    vr2 = r[3,:] #Moon velocity
    r3 = array([R*cos(t),.5*R*sin(2*t),0],float)  +r[4,:] #Satellite position Figure 8 parameterization
    vr3 = r[5,:] #Satellite velocity
    fr1 = -G*M2*(r1 -r2)/(abs_v((r1-r2))**3)
    fr2 = -G*M1*(r2 -r1)/(abs_v((r2-r1))**3) 
    fr3 = (G*M1*(r3 -r_1)/(abs_v((r3-r_1))**3)) -(G*M2*(r3 -r_2)/(abs_v((r3-r_2))**3)) +2*omega_0*array([vr3[1],-vr3[0],0],float)+ (omega_0**2)*array([r3[0],r3[1],0],float) #Gravitational interaction of Satellite with Earth, Moon, Coriolis, and Centrifugal forces
    return array((vr1,fr1 ,vr2,fr2,vr3,fr3),float)



def RungeKutta4o(g,ksi10,vksi10,ksi20,vksi20,ksi30,vksi30,a,b): #Runge Kutta 4th order
    N=1000
    M = 6    
    h = float((b-a)/N)
    t = linspace(a,b,N)
    x1 = zeros((N,3),float)
    x2 = zeros((N,3),float)
    x3 = zeros((N,3),float)
    vx1 = zeros((N,3),float)
    vx2 = zeros((N,3),float)
    vx3 = zeros((N,3),float)
    r = array((ksi10,vksi10,ksi20,vksi20,ksi30,vksi30),float)
    k1 = zeros((M,3),float)
    k2 = zeros((M,3),float)
    k3 = zeros((M,3),float)
    k4 = zeros((M,3),float)
    for i in range(N):
        x1[i,:] = r[1,:]
        vx1[i,:] = r[0,:]
        x2[i,:] = r[3,:]
        vx2[i,:] = r[2,:]
        x3[i,:] = r[5,:]
        vx3[i,:] = r[4,:]
        k1 = h*g(r,t[i])
        k2 = h*g(r +.5*k1,t[i]+.5*h)
        k3 = h*g(r +.5*k2,t[i]+ .5*h)
        k4 = h*g(r +k3,t[i]+h)
        r += (1/6)*(k1 + 2*k2 + 2*k3 + k4)
    return t,x1,x2,x3,vx1,vx2,vx3 

cla()   # Clear axis
clf()
r_i0 = r_2 + array([0,R_e+300e3,0],float) # Satellite is initially in Earth orbit
vr_i0 = array([11000,0,0],float) # Initial velocity of satellite
t,R1,R2,R3,vR1,vR2,vR3  = RungeKutta4o(F,r_1,omega,r_2,omega,r_i0,vr_i0,0,10*T_a ) 
plot(R3[:,0],R3[:,1])  #Plots the Satellite orbit R3[:,0] is the x position of the satellite and R3[:,1] is the y position of the satellite
show() 

enter image description here

  • Welcome to stackexchange! If you haven't already, consider taking the tour. This is not a site for debugging programs, so you'll need to do at least some of that yourself first. For example, what does happen when you run it? Can you try a two-body (basically a one-body) problem and get your satellite to orbit the Earth at least? I ran your script and R3 doesn't even change - your satellite isn't even moving, so you probably have a simple script-debugging issue. – uhoh Apr 18 '17 at 05:29
  • Try to make a much simpler simulation work correctly first, then add complexity one bit at a time. Is the RK4 algorithm working correctly - has it been independently debugged? It seems strange - you dimension $k_1, k_2, k_3, k_4$ as arrays, then immediately assign them as scalars. Actually the way the RK4 algorithm is written suggests you aren't really familliar with python or numpy. Learn them first! – uhoh Apr 18 '17 at 05:30
  • @uhoh I have made simpler simulation first it worked, I assumed that my Satellite was moving because I can plot it's position , When I run the code it spirals out. – FireFistAce Apr 18 '17 at 05:34
  • @uhoh my function returns arrays that is why I wrote it like that so I assign the arrays when I run the code – FireFistAce Apr 18 '17 at 05:36
  • @ uhoh You need to to run R3[:,0] as R is just a constant distance – FireFistAce Apr 18 '17 at 05:43
  • 1
    @uhoh I added a picture of what I plot and when run print(R3[:,0]) I get many differing values – FireFistAce Apr 18 '17 at 05:54
  • @uhoh ok and thanks for the suggestion on it helped me clarify my question a bit – FireFistAce Apr 18 '17 at 06:01
  • Aha! I use Python 2 (common for science/engineering) and so anything**(1/2) returns 1.0 and 1/6 returns zero, since Python 2 uses integer math on integer types, it does not upcast to floats. Now I can get your spiral, yay! First suggestion, your time step h is 0.01 month, or about 6.5 hours. You need to use much smaller time steps of the order of minutes to handle the orbit around the earth. Second, in the CR3BP you just leave the Earth and Moon fixed, you don't calculate their motion. Only the spacecraft's position should appear in the calculation of acceleration (don't say "Force"). – uhoh Apr 18 '17 at 07:09
  • For better python, try to stop using so many arrays if it gets slow. In the loop, every time you calculate a new position, append it to a list. When you are done, convert the list to an array. And like I said, don't let any information about the Earth or Moon even get into the calculation. The whole point of using the CR3BP formalism is to reduce the problem to a one body problem in a rotating frame, with an effective force that includes centrifugal. – uhoh Apr 18 '17 at 07:16
  • Look at the Python in this question where I"m doing halo orbits. Usually CR3BP is solved in dimensionless, or reduced units. The Earth-Moon distance is equal to 1.0, and the Earth-Moon period is equal to $2\pi$ (dimensionless). You can also see a nicer way to use numpy to do the math. In this case I've used scipy.odeint instead of the manual RK4. I recommend you that to first make sure that your RK4 gives the same answer as odeint. – uhoh Apr 18 '17 at 07:20
  • 1
    @uhoh I keep the Earth and Moon positions constant and don't vary them that is why I use r_1, r_2 which don't vary. For the second derivative terms I keep the gravitational terms in because the satellite is still in there potential and it energy will change depending on it's distance relative to them and I was given the problem with those terms in there but without there distances varying only the relative distance of the satellite relative to them. – FireFistAce Apr 18 '17 at 16:01
  • @uhoh I am not sure what you mean written by a third party I wrote the script based on the parameters I was given – FireFistAce Apr 18 '17 at 16:41
  • I'm voting to close this question as off-topic because it's asking why a third-party's poorly-thought-out algorithm doesn't run with apparently no first-hand knowledge of how it works. – uhoh Apr 18 '17 at 16:45
  • @uhoh if you don't want to help fine but your suggestions don't help me with the main part of my question which is how to change the current trajectory to orbit both bodies making the program run faster and working in normalized units do not change the fundamental shape of the curve which is what I needed help with. – FireFistAce Apr 18 '17 at 16:45
  • @uhoh Even if I remove the force terms from the satellites which does not make sense considering as I said the satellite is still in the potential of the system hence why I keep those terms it still does not change the spiral pattern only its magnitude – FireFistAce Apr 18 '17 at 16:49
  • @uhoh Since you are so certain I have no understanding of the topic maybe you should read chapter 7 of this book which shows that the equations of motion in a co rotating reference in which this program is working is as I have indicated in my question above. a = Fnet - F_coriolis F_centrifugal http://farside.ph.utexas.edu/teaching/336k/Newton.pdf , I have put a reference above in the question now that shows why my equation makes sense here is the reference as well http://farside.ph.utexas.edu/teaching/336k/Newtonhtml/node123.html – FireFistAce Apr 18 '17 at 19:26
  • They don't need to be big 2D arrays, and they don't need to be recalculated at every time step. You calculate them once in the main program. Adding the link to the math is extremely helpful to those who may want to help debug; +1 for math! Since you will need time steps of 1 minute or probably a few seconds with RK4, a two-week mission will need 200,000 to 1,000,000 time steps. If you want to maintain a dozen 3 x 1,000,000 arrays in memory and pop them in and out of cache, this program will be extremely slow. – uhoh Apr 18 '17 at 19:32
  • @uhoh Thanks for the up vote, are you saying that lists would be more efficient in this regard as far as speed goes – FireFistAce Apr 18 '17 at 19:37
  • I'll repeat my recommendation that you get it to work with scipy.odeint first, then try to see if it is even possible with RK4, which needs much much smaller time steps than the much higher order, variable step-size algorithms in odeint. Again, look at the python here. Fastest way to get a program to work is to get small parts of it to work, one at a time. Much faster than just posting a doesn't work script in stackexchange. – uhoh Apr 18 '17 at 19:37
  • Python manages large lists in very agile, efficient, and optimized ways. NumPy arrays are big dumb blocks of memory. They are extremely fast for many operations, but not random-access or indexed access from an explicit python loop. – uhoh Apr 18 '17 at 19:40
  • Here is RK4 in python. It has 2D arrays because in this case I have done what you do - preallocate and fill the arrays, but it's OK here because n=1000 only, and I did that because it is # written for readability, not speed. For n=1000000 you drop the big arrays and just .append() each new position to a list. Each position could be a small array, or a list. btw I just checked it and it still works. If you download blender and paste that script into the script editor and hit run, it generates an animation that works. – uhoh Apr 18 '17 at 20:24
  • Spiraling out suggests that your simulation isn't conserving energy, which could be caused by either using too long an integration timestep, or a bug in your integration algorithm. – djr Apr 18 '17 at 22:09
  • @djr That is a very good point. However in the data shown, the time step is 6.5 hours, i.e. four complete orbits around the Earth, and it seems to start at a point about 300km from the center of the Earth! Changing these does not help, the spiral is rock-solid meaning it's just junk. This is a poorly-written, never-worked script posted in hopes that someone will magically make it work somehow, or just post a new one. – uhoh Apr 19 '17 at 10:35
  • @djr could this also be because the RK4 method has tendency to not conserve energy and you need to have an adaptive method to correct it? – FireFistAce Apr 20 '17 at 02:46
  • It can be a problem with any numerical integration scheme, particularly if the timestep is too long. As @uhoh pointed out, you're using 6.5 hour timesteps, which is far too long. Get this method running correctly before worrying about other ones. – djr Apr 20 '17 at 09:16

1 Answers1

3

What you are asking for is called a free return trajectory.

I will not be debugging your program or solving the problem for you (that's your homework), but I will pass on some advice given by Bate, Mueller & White*:

  • There is more than one solution.
  • Don't expect an exact solution from whatever your initial conditions may be.
  • Start off by using the patched conic method.

You can then refine the approximate answer with a more exact numerical integration. If your integrator gives a wildly different answer from patched conics, try inputting some simple Earth orbits and see if the answers make sense. You can check the orbit against an analytical method for perturbations by the moon. It is likely that the integrator is buggy.

Use the patched conic approximation to get a feel for how the evolution of the system is affected by small changes in the initial conditions. Think of what happens at the patch points.

*Fundamentals of Astrodynamics, 1971, Dover, exercise 7.12 on p. 354.

user25972
  • 431
  • 3
  • 5