램버트 문제의 해(https://pasus.tistory.com/316)는 두 위치

일반적인 섭동력 (J2 섭동력, 태양복사압력, 항력, 달 또는 태양 등의 제3의 중력 등)의 경우 이러한 오차 거리(miss distance)가 크지 않기 때문에, 출발 위치
슈팅방법은 기본적으로 경계값 문제를 초기값 문제로 바꾸어 해를 구하는 방법으로서, 초기값으로부터 산출된 최종값과 목표값 간의 차이를 이용하여 원래 초기값을 수정한다.
최종 위치 오차
여기서 미분
식 (1)에 의하면 최종 위치벡터 오차에 대한 초기 속도벡터 오차
추정된 속도벡터 오차를 속도벡터
식 (2)의 자코비안 또는 민감도 행렬
여기서
이제 J2 섭동력 하에서도 궤적이 시간
J2 섭동력을 포함한 램버트 문제는 다음과 같다.
여기서
식 (4)에 의하면 자코비안
그리고
그런 후 이번에는
마찬가지로
동일한 방법으로
자코비안을 구한 후에는 식 (3)으로 초기 속도벡터를 보정하면 된다. 그리고 다시 새로운 속도벡터를 이용하여 자코비안을 다시 계산하고 속도벡터를 보정하는 프로세스를 오차 거리가 일정 수준 이하로 작아질 때 까지 계속 반복한다.

수치 예를 들어보자. 램버트 문제의 경계조건은 다음과 같다.
위 문제를 범용변수 기반 램버트 알고리즘(https://pasus.tistory.com/316)으로 푼 초기 속도는 다음과 같다.
식 (5)에서
이 오차 거리를 감소시키기 위하여 초기 속도벡터를 슈팅 방법으로 보정하면 결과는 다음과 같다. 우선 3회의 반복횟수 만에 초기 속도벡터가 다음 값으로 수정되었다.
보정된 속도와 원래 속도의 크기 차이는
이제 보정된 속도벡터를 초기값으로 하여 최종 위치벡터를 계산하고 오차 거리를 구하면
다음은 자코비안 행렬 (또는 민감도 행렬)을 계산하는 알고리즘을 매트랩 코드로 구현한 것이다.
jacobian_shooting.m
function J = jacobian_shooting(odefun, y0ini, tof, dv)
% J = jacobian_shooting(odefun, y0ini, tof, dv)
% given odefun, y0in, tof, dv
% compute 3x3 Jacobian for shooting method
%
% Input odefun: ODE function
% y0ini: initial position and velocity vector in km, km/s
% = [x y z vx vy vz]'
% tof: time of flight in sec
% dv: small velocity amoint used for finite differences in km/s
% Output J: Jacobian
%
% all in inertial frame (ECI)
%
% coded by st.watermelon
J = zeros(3, 3);
tspan = [0:tof/100:tof]';
OPTIONS = odeset('RelTol',3e-14,'AbsTol',1e-15);
% finite differences with +/- vx
y0 = y0ini + [0 0 0 +dv 0 0]';
[t,y] = ode113(odefun, tspan, y0, OPTIONS);
rplus = y(end,1:3)';
y0 = y0ini + [0 0 0 -dv 0 0]';
[t,y] = ode113(odefun, tspan, y0, OPTIONS);
rminus = y(end,1:3)';
J(:, 1) = (rplus-rminus)/(2*dv);
% finite differences with +/- vy
y0 = y0ini + [0 0 0 0 +dv 0]';
[t,y] = ode113(odefun, tspan, y0, OPTIONS);
rplus = y(end,1:3)';
y0 = y0ini + [0 0 0 0 -dv 0]';
[t,y] = ode113(odefun, tspan, y0, OPTIONS);
rminus = y(end,1:3)';
J(:, 2) = (rplus-rminus)/(2*dv);
% finite differences with +/- vz
y0 = y0ini + [0 0 0 0 0 +dv]';
[t,y] = ode113(odefun, tspan, y0, OPTIONS);
rplus = y(end,1:3)';
y0 = y0ini + [0 0 0 0 0 -dv]';
[t,y] = ode113(odefun, tspan, y0, OPTIONS);
rminus = y(end,1:3)';
J(:, 3) = (rplus-rminus)/(2*dv);
다음은 식 (5)의 운동 방정식을 구현한 코드다.
orbitbody_J2.m
function ydot=orbitbody_J2(t,y)
% two-body orbital equation with J2
% coded by st.watermelon
mu=398600;
Rearth=6378;
J2=1.0826269e-3;
r=y(1:3);
v=y(4:6);
normr=norm(r);
rhat=r/normr;
acc=-(mu/(normr*normr))*rhat;
% J2
tmp = 5*r(3)^2/normr^2;
acc=acc + 3/2*J2*mu/normr^5*Rearth^2* ...
[r(1)*(tmp-1); r(2)*tmp-1; r(3)*(tmp-1)];
%acc=acc - (mu*J2*Rearth*Rearth/2)* ...
% ((6*z/(normr^5))*khat+((3/(normr^4))-(15*z*z/(normr^6)))*rhat);
ydot=zeros(6,1);
ydot(1:3)=v;
ydot(4:6)=acc;
다음은 수치 예제를 실행한 파일이다.
orbit_simul.m
%
% J2-perturbed Lambert correction with shooting method
% coded by st.watermelon
clear all
% data
r1=[5000 10000 2100]';
r2=[-14600 2500 7000]';
tof=60*60; % 1 hour
OPTIONS = odeset('RelTol',3e-14,'AbsTol',1e-15);
% 1. Lambert solution
[v1, v2] = lambert(r1, r2, tof);
% 2. check solution accuracy
y0=[r1;v1];
[t,y]=ode113(@orbitbody, [0:60:tof]',y0,OPTIONS);
r2_computed = y(end,1:3)';
err_is = r2_computed-r2;
fprintf('Lambert solver accuracy \n');
fprintf('final error distance = %e m \n\n', norm(err_is)*100);
% 3. check again with J2 perturbation
y0=[r1;v1];
[t,yJ2]=ode113(@orbitbody_J2, [0:60:tof]',y0,OPTIONS);
r2_J2computed = yJ2(end,1:3)';
errJ2_is = r2_J2computed-r2;
fprintf('J2-perturbed Lambert solver accuracy \n');
fprintf('final error distance = %e m \n\n', norm(errJ2_is)*100);
% 4. correction with shooting method
v1_J2 = v1;
for iter=1:10
y0=[r1;v1_J2];
[t,y]=ode113(@orbitbody_J2, [0:60:tof]',y0,OPTIONS);
J = jacobian_shooting(@orbitbody_J2, [r1; v1_J2], tof, 0.01);
correc = inv(J)*(y(end,1:3)'-r2);
v1_J2 = v1_J2 - correc;
if norm(correc)<1e-8
break
end
end
v1_J2
fprintf('shooting iteration = %d \n', iter);
fprintf('initial velocity differences = %e m/s \n\n', norm(v1-v1_J2)*100);
% 5. check corrected accuracy
y0=[r1;v1_J2];
[t,yJ2_c]=ode113(@orbitbody_J2, [0:60:tof]',y0,OPTIONS);
r2_J2c = yJ2_c(end,1:3)';
errJ2c_is = r2_J2c-r2;
fprintf('corrected solution accuracy \n');
fprintf('final error distance = %e m \n', norm(errJ2c_is)*100);
'항공우주 > 우주역학' 카테고리의 다른 글
다중 슈팅방법 (Multiple Shooting Method) 예제 (0) | 2024.05.14 |
---|---|
다중 슈팅방법 (Multiple Shooting Method) (0) | 2024.05.14 |
중력 영향권 (Sphere of Influence) (0) | 2024.01.08 |
감시정찰 (Surveillance and Reconnaissance) 영역 계산 (0) | 2023.12.26 |
램버트 문제 (Lambert’s problem)의 해 (0) | 2023.12.10 |
댓글