pythongekkoipopt

Minimize value by manipulating variables in GEKKO+Python


This is an extension of this question.

I want to minimize the delta-V (impulse) by manipulating the launch date, flyby date, and arrival date. These are defined as my manipulation variables as follows:

# Manipulating variables and initial guesses
launch = m.MV(value = 2460159.5, lb = 2460159.5, ub = 2460525.5)
launch.STATUS = 1
# flyby = m.MV(value = 2460424.5, lb = 2460342.5, ub = 2460525.5) # Venus/Mars
flyby = m.MV(value = 2460846.5, lb = 2460704.5, ub = 2460908.5) # Jupiter
flyby.STATUS = 1
# arrive = m.MV(value = 2460694.5, lb = 2460480.5, ub = 2460845.5) # Venus/Mars
arrive = m.MV(value = 2461534.5, lb = 2461250.5, ub = 2461658.5) # Jupiter
arrive. STATUS = 1

I then define my variables as follows:

# Variables
r1  = m.Array(m.Var, 3, value = 0, lb = -1e10, ub = 1e10)
v1  = m.Array(m.Var, 3, value = 0, lb = -1e5, ub = 1e5)
r2  = m.Array(m.Var, 3, value = 0, lb = -1e10, ub = 1e10)
v2  = m.Array(m.Var, 3, value = 0, lb = -1e5, ub = 1e5)
r3  = m.Array(m.Var, 3, value = 0, lb = -1e10, ub = 1e10)
v3  = m.Array(m.Var, 3, value = 0, lb = -1e5, ub = 1e5)
l   = m.Array(m.Var, 3, value = 0, lb = -1e5, ub = 1e5)
imp = m.Array(m.Var, 3, value = 0, lb = -1e5, ub = 1e5)

I was following the answer to the previous question, and used the same format for all variables. I had originally defined my variables as follows (based on the previous answer):

# Variables
r1  = m.Var(value = np.array([0, 0, 0]), lb = -1e10, ub=1e10, name = "r1")
v1  = m.Var(value = np.array([0, 0, 0]), lb = -1e5, ub = 1e5, name = "v1")
r2  = m.Var(value = np.array([0, 0, 0]), lb = -1e10, ub = 1e10, name = "r2")
v2  = m.Var(value = np.array([0, 0, 0]), lb = -1e5, ub = 1e5, name = "v2")
r3  = m.Var(value = np.array([0, 0, 0]), lb = -1e10, ub = 1e10, name = "r3")
v3  = m.Var(value = np.array([0, 0, 0]), lb = -1e5, ub = 1e5, name = "v3")
l   = m.Var(value = np.array([0, 0, 0]), lb = -1e5, ub = 1e5, name = "launch")
imp = m.Array(m.Var, 3, value = 0, lb = -1e5, ub = 1e5)

While the only variable I am trying to minimize is 'imp', I do intend to use the final values of all the other variables for further analysis, so I want to be able to get the values.

To determine the impulse (delta-V), I am doing a slingshot maneuver, which is defined as follows:

def slingshot():
    # Dates
    date_launchE = Time(str(launch.value), format="jd", scale="utc").tdb
    date_flyby = Time(str(flyby.value), format="jd", scale="utc").tdb # Mars
    date_arrivalE = Time(str(arrive.value), format="jd", scale="utc").tdb

    venus = Ephem.from_body(Venus, time_range(date_launchE, end=date_arrivalE, periods=500))
    earth = Ephem.from_body(Earth, time_range(date_launchE, end=date_arrivalE, periods=500))

    r_e0, v_e0 = earth.rv(date_launchE)

    ss_e0 = Orbit.from_ephem(Sun, earth, date_launchE)
    ss_fly = Orbit.from_ephem(Sun, venus, date_flyby)

    # Lambert solution to get to flyby planet
    man_launch = Maneuver.lambert(ss_e0, ss_fly)

    # Cruise to flyby planet
    cruise1 = ss_e0.apply_maneuver(man_launch)
    cruise1_end = cruise1.propagate(date_flyby)

    ss_earrive = Orbit.from_ephem(Sun, earth, date_arrivalE)

    # Lambert solution to the flyby
    man_flyby = Maneuver.lambert(cruise1_end, ss_earrive)
    imp_a, imp_b = man_flyby.impulses

    # Apply the maneuver
    cruise2, ss_etarget = cruise1_end.apply_maneuver(man_flyby, intermediate=True)

    # Propagate the transfer orbit until return to Earth
    cruise2_end = cruise2.propagate(date_arrivalE)

    ss_target = Orbit.from_ephem(Sun, earth, date_arrivalE)

    final = Ephem.from_orbit(cruise2_end, date_arrivalE)

    r_final, v_final = final.rv(date_arrivalE)
    r1, v1 = Ephem.from_orbit(ss_e0, date_launchE).rv(date_launchE)
    r2, v2 = Ephem.from_orbit(ss_fly, date_flyby).rv(date_flyby)
    r3, v3 = Ephem.from_orbit(ss_target, date_arrivalE).rv(date_arrivalE)
    
    return r1[-1].value, v1[-1].value, r2[-1].value, v2[-1].value, r3[-1].value, v3[-1].value, v_final[-1].value, imp_a[-1].value

However, when I call the function, no optimization takes place, and the return value just ends up being based on the initial guesses for my dates.

# Slingshot maneuver
r1, v1, r2, v2, r3, v3, v_final, imp = slingshot()

From the previous question, I see that I was informed not to change the variables within the function. I recognize that I am not passing anything into my function, but even if I do pass the manipulation variables, the result is the same.

So, my question is then:

How do I use my function to minimize the impulse by manipulating the dates?

I based my initial problem with the function on a different question I had posted. I thought I had modified that GEKKO/IPOPT problem appropriately for this problem, but apparently I did not.


Solution

  • I redefined the variables as:

    # Variables
    date_launchE = m.Var(value = Time(str(launch.value), format="jd", scale="utc").tdb)
    date_flyby = m.Var(value = Time(str(flyby.value), format="jd", scale="utc").tdb)
    date_arrivalE = m.Var(value = Time(str(arrive.value), format="jd", scale="utc").tdb)
    imp = m.Array(m.Var, 3, value = slingshot(), lb = -1e3, ub = 1e3)
    

    Then used the dates in my slingshot() function.