У меня есть задание, и часть его включает в себя запуск спутника на орбиту Земли и Луны хотя бы один раз. Как бы то ни было, независимо от того, как я устанавливаю свое начальное условие или параметризую свое положение и время, меняю его, мой спутник не будет вращаться вокруг Луны и не вернется. Обратите внимание, что и Луна, и Земля лежат на оси x, система находится в их совместном вращении, я использую Рунге Кутта четвертого порядка для моделирования орбиты.
Обновление 1: после некоторого предложения из комментариев ниже моего сценария, чтобы объяснить проблему немного больше, когда я запускаю свой код, спутник выходит по спирали и не вращается по орбите, я также добавил график спутника
Обновление 2: Для тех, кому интересно, откуда я взял свой термин ускорения для спутника и почему он включает в себя Кориолиса и центробежную силу, а также гравитационную силу между спутником и Землей, а также спутником и луной, см. эту ссылку http://farside.ph.utexas. edu/teaching/336k/Newtonhtml/node123.html и глава 7 этого http://farside.ph.utexas.edu/teaching/336k/Newton.pdf
Обновлено 3:Исправлена ошибка в положении спутника и опечатка в комментариях кода,обновлено изображение, которое соответствовало исправлению в коде
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()
То, о чем вы просите, называется траекторией свободного возврата .
Я не буду отлаживать вашу программу или решать проблему за вас (это ваша домашняя работа), но передам несколько советов, данных Бейтом, Мюллером и Уайтом*:
Затем вы можете уточнить приблизительный ответ с помощью более точного численного интегрирования. Если ваш интегратор дает совершенно другой ответ, чем исправленные коники, попробуйте ввести несколько простых орбит Земли и посмотрите, имеют ли ответы смысл. Вы можете проверить орбиту с помощью аналитического метода для возмущений Луны. Скорее всего глючит интегратор.
Используйте аппроксимацию с заплатками, чтобы понять, как на эволюцию системы влияют небольшие изменения начальных условий. Подумайте о том, что происходит в точках исправления.
*Основы астродинамики, 1971, Дувр, упражнение 7.12 на с. 354.
ооо
ооо
FireFistAce
FireFistAce
FireFistAce
FireFistAce
FireFistAce
ооо
anything**(1/2)
возвращает1.0
и1/6
возвращает ноль, поскольку Python 2 использует целочисленную математику для целочисленных типов, он не преобразуется в числа с плавающей запятой. Теперь я могу получить твою спираль, ура! Первое предложение, ваш временной шагh
составляет 0,01 месяца или около 6,5 часов. Вам нужно использовать гораздо меньшие временные шаги порядка минут, чтобы управлять орбитой вокруг Земли. Во-вторых, в CR3BP вы просто оставляете Землю и Луну неподвижными, вы не рассчитываете их движение. При вычислении ускорения должно учитываться только положение космического корабля (не говорите «Сила»).ооо
list
. Когда вы закончите, преобразуйте список в массив. И, как я уже сказал, не позволяйте никакой информации о Земле или Луне даже попасть в расчеты. Весь смысл использования формализма CR3BP состоит в том, чтобы свести задачу к задаче с одним телом во вращающейся системе отсчета с эффективной силой, включающей центробежную.ооо
scipy.odeint
вместо ручного RK4. Я рекомендую вам сначала убедиться, что ваш RK4 дает тот же ответ, что иodeint
.FireFistAce
FireFistAce
ооо
FireFistAce
FireFistAce
FireFistAce
ооо
+1
по математике! Поскольку вам потребуются временные шаги в 1 минуту или, возможно, несколько секунд с RK4, для двухнедельной миссии потребуется от 200 000 до 1 000 000 временных шагов. Если вы хотите хранить в памяти дюжину массивов размером 3 x 1 000 000 и выталкивать их из кэша, эта программа будет работать очень медленно.FireFistAce
ооо
scipy.odeint
сначала вы должны заставить его работать, а затем попытаться увидеть, возможно ли это даже с RK4, для которого требуются гораздо меньшие временные шаги, чем алгоритмы гораздо более высокого порядка с переменным размером шага вodeint
. Опять же, посмотрите на питона здесь . Самый быстрый способ заставить программу работать — заставить ее работать по одной за раз. Гораздо быстрее, чем просто опубликовать неработающий скрипт в stackexchange.ооо
ооо
n=1000
только, и я сделал это, потому что это# written for readability, not speed
. Потомуn=1000000
что вы отбрасываете большие массивы и только.append()
каждую новую позицию в список. Каждая позиция может быть небольшим массивом или списком. Кстати, я только что проверил это, и это все еще работает. Если вы загрузите блендер и вставите этот скрипт в редактор скриптов и нажмете «Выполнить», он создаст работающую анимацию.диджей
ооо
FireFistAce
диджей