Skip to content
This repository has been archived by the owner on Oct 14, 2023. It is now read-only.

Lambert method for in-plane transfer #904

Closed
tmamedzadeh opened this issue Apr 12, 2020 · 10 comments
Closed

Lambert method for in-plane transfer #904

tmamedzadeh opened this issue Apr 12, 2020 · 10 comments

Comments

@tmamedzadeh
Copy link

tmamedzadeh commented Apr 12, 2020

I'm trying to solve the transfer between a circular orbit with 200km radius and an orbit with 200km perigee and 8000km apogee.

The optimal transfer is hoffman, however, izzo.lambert gives different result.

My code:

from astropy import units as u
from poliastro.bodies import Earth
from poliastro.iod import izzo
from poliastro.core.elements import coe2rv
from poliastro.util import norm
import math
import time

Earth_k = Earth.k
Req = Earth.R.to(u.km).value

def keplerian2cartesian(kepler):

    a=(kepler[0]+kepler[1]+Req*2)*1000/2 * u.m
    e=(kepler[0]-kepler[1])/(kepler[0]+kepler[1]+Req*2)

    (R,V)=coe2rv(Earth.k,a,e,kepler[2],kepler[3],kepler[4],kepler[5])

    return [R * u.m] + [V * u.m/u.s]

# Checking different transfer times
def transfer_time(DV_min,vector0,vector,period):

    init_t=10
    t_value=init_t
    (r0,r,v0,v)=(vector0[0],vector[0],vector0[1],vector[1])

    while init_t<period:

        tof = init_t * u.min

        try:
            (f_v0, f_v), = izzo.lambert(Earth_k, r0, r, tof)
        except:
            init_t+=1
            continue

        DV0=norm(f_v0-v0).value*1000
        DV=norm(f_v-v).value*1000

        if(DV0+DV<DV_min):
            t_value=init_t
            DV0_value=DV0
            DV_value=DV
            DV_min=DV0+DV

        init_t+=1

    return (t_value,DV_value,DV0_value)


# Checking different initial and final true anomalies
def transfer_tetta(kepler0,kepler):
    DV_min=100000
    final_tetta=0

    a=(kepler[0]+kepler[1]+Req*2)*1000/2
    period=math.ceil(math.sqrt((a**3/Earth.k.value)*4*(math.pi)**2)/60)

    while final_tetta<360:
        init_tetta=0
        while init_tetta<360:
            vector0=keplerian2cartesian(kepler0 + [init_tetta*math.pi/180])
            vector =keplerian2cartesian(kepler  + [final_tetta*math.pi/180])
            try:
                (init_t,DV,DV0)=transfer_time(DV_min,vector0,vector,period)
            except:
                init_tetta+=5
                continue

            if DV+DV0<DV_min:
                DV_min=DV+DV0
                (t_value,DV0_value,DV_value,init_tetta_value,final_tetta_value)=(init_t,DV0,DV,init_tetta,final_tetta)

            init_tetta+=5
        final_tetta+=5

    print("t: ", t_value, "DV_init: ", DV0_value,"DV_final: ", DV_value)
    print("DV: ", DV_min)
    print("Init tetta: ", init_tetta_value, "Final tetta: ", final_tetta_value)

# 1->2
transfer_tetta([200,  200, 64.3*math.pi/180, 0, 300*math.pi/180],[8000, 200, 64.3*math.pi/180, 0, 300*math.pi/180])

@astrojuanlu
Copy link
Member

Hello @Tarlan0001! No shame in opening an issue and then discovering the answer yourself :) Would you be so kind to restore the original text and point out how did you fix the problem?

If you ever have other questions, feel welcome to join our chat. Cheers!

@tmamedzadeh
Copy link
Author

@astrojuanlu Hi. I didn't solve it yet. I deleted it because it's not a matter of a ticket right now, I have to find the issue.

However, if you could help me with izzo.lambert for my problem, I would appreciate.

@tmamedzadeh tmamedzadeh reopened this Apr 12, 2020
@astrojuanlu
Copy link
Member

Sure thing! Could you please share the code you're using? If it's long, you can upload it to https://gist.github.com/

@astrojuanlu
Copy link
Member

By the way, https://doi.org/10.2514/3.20941 contains a simple proof of the optimality of the Hohmann transfer. The problem with applying the Lambert problem in this case is that it's ill conditioned if the transfer angle is 180 degrees.

@tmamedzadeh
Copy link
Author

tmamedzadeh commented Apr 12, 2020

@astrojuanlu Sure, added my code. I guess, the result should be a maneuver at 0 true anomaly (perigee) and zero maneuver at apogee.

Thank you for the paper!

@astrojuanlu
Copy link
Member

I recommend you to simplify by code by using from poliastro.core.elements import coe2rv and from poliastro.util import norm.

Also, I am not confident at all that this should work, because of the singularity I mentioned.

@astrojuanlu
Copy link
Member

@astrojuanlu
Copy link
Member

I gave a detailed answer with my perspective on the theoretical aspects of this at Space.SE. It's difficult for me to make sense of the code if I don't understand the research question.

@tmamedzadeh
Copy link
Author

@astrojuanlu Thank you for the detailed answer!
Indeed, I want to get the same result with Lambert solver, as it would be with the Hoffman transfer.
Now it gives an optimal transfer starting from 0 deg true anomaly and finishing at 185 deg (which is close to Hoffman). I checked an interval of transfer times with 1 minute period.

I accepted your answer, however, if it's possible, I would appreciate your time to check the code above to ensure, that the problem is in singularity.

@tmamedzadeh
Copy link
Author

Well, I've got the result 0 deg initial and 181 deg final with the Lambert solver. However, the DV is a little higher than with the Hoffman.
Closing this ticket, thank you!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants