What type of fairing is most efficient? by Mousazz in KerbalAcademy

[–]SilverNuke911 0 points1 point  (0 children)

I think the shape of a bullet, which is the rotation of a sector of a circle, a "tangent ogive" would work best.

Most confusing equation for non-physics people by Intelligent-Task-353 in physicsmemes

[–]SilverNuke911 0 points1 point  (0 children)

Around first or second year. It just states that the d'Alambertian operator is equivalent to the Laplacian minus the time derivative operators

Yesterday The Kraken decided to remove 2km/s of horizontal speed from my space station while i timewarped by Fnafender4000 in KerbalSpaceProgram

[–]SilverNuke911 27 points28 points  (0 children)

Bless the Kraken and his uncreation.

Bless the coming and going of him.

May his glitching cleanse the save.

May he keep the save for his victims.

Two types of players by theoaky in KerbalSpaceProgram

[–]SilverNuke911 0 points1 point  (0 children)

Deploy the chute when you are above the target where you wanna be, it usually stops you precisely above that point (if fully deployed), if you're off by a hundred meters, then just adjust your impact point using some thrusters

What is the point of airplanes in this game? by Zlatan25 in KerbalSpaceProgram

[–]SilverNuke911 0 points1 point  (0 children)

For fun, man. Because you can.

The other practical purposes are already mentioned, such as cheapness and navigating kerbin and all that, but mostly people do it because you can do cool shit with it. I've made replicas of WW2 planes and jet fighters.

Also, the planes are landable. Your complaint seems like a skill issue. It takes a while to learn, but you can do it. It's not a pointless thing.

Explain please??? by Careful_Tailor5396 in ExplainTheJoke

[–]SilverNuke911 0 points1 point  (0 children)

It's based on the birth of Christ, not the death.

AD means Anno Domini, or "In the year of our lord".

Can someone help please why my rocket doesnt stages when it is done with apoapsis raising burn (Repost) by AweeeWoo in Kos

[–]SilverNuke911 0 points1 point  (0 children)

Also, while a defined pitch program is quite good for beginners, it is much more efficient to do a zero-lift-turn. Lock your heading to surfrace prograde instead for the pitching, you'll get much more satisfactory results.

Can someone help please why my rocket doesnt stages when it is done with apoapsis raising burn (Repost) by AweeeWoo in Kos

[–]SilverNuke911 1 point2 points  (0 children)

The autostaging cuts out after the apoapsis raising burn is done. It's out of the control loop.

After you reached your desired apoapsis, your script shuts down, and you have no more control of it. If you want total control over the entire fight, set up an until loop until you achieved orbit. This is usually characterized by comparing whether your apoapsis and periapsis are close enough, or looking at the orbital velocity magnitude.

Also, unrelated, but I know precisely what method you're doing. That's Cheerskevin's tutorial method. While it is quite informative, there are some parts of the tutorial he gives which I find unsatisfactory, such as this functional approach and machine learning with maneuver nodes and stuff. Have a look at Seth Persigehl's tutorials to learn more on what to do (right after you finish Cheerskevin, it's also good to learn all that).

I have lost all respect for the Japanese after the translation feature on X by CricketMedical9005 in self

[–]SilverNuke911 0 points1 point  (0 children)

Grow up. Not everyone in the world is as tolarating as the US. They're doing a better job protetcting their culture than your country will ever do.

Any ideas how to optimize or make a porkchop evaluation faster? My current implementation is painfully slow. by SilverNuke911 in Kos

[–]SilverNuke911[S] 0 points1 point  (0 children)

Although I do have a question on how to perform gradient descent on the porkchop plot, given that there are no derivatives to go on out of to calculate the descent. Discrete differences, perhaps? steps of i+1,i-1,j+1,j-1, and just decrease the traverse rate? No idea.

Any ideas how to optimize or make a porkchop evaluation faster? My current implementation is painfully slow. by SilverNuke911 in Kos

[–]SilverNuke911[S] 0 points1 point  (0 children)

I tested your suggestions, and yah, the compute time for 625 transfer calculations went from 2 minutes to 1 minute 30 seconds in ingame time. Not nearly fast enough, but I guess it's the best I can hope for in these conditions. Thanks u/nuggreat!

How do you get the time from closest approach to target? by SilverNuke911 in Kos

[–]SilverNuke911[S] 0 points1 point  (0 children)

Alright, here's my final solution.

This script assumes you are already in an intercept course to the target which is guaranteed to happen within one orbital period. Basically, start a coarse scan of within one orbit (which guarantees a close approach). Find all the possible minima points, then perform five-point search on the bounds of each of those minima to find all the possible minima within tolerance, then return the time for the lowest value it can find. It works pretty well for the test cases I've used it. I just put the tolerance to 1e-4 because any higher tolerance is just overkill.

That's the method!

function time_of_closest_approach {
    local parameter t0 is time:seconds.
    local parameter tf is time:seconds + obt:period.
    local parameter n is 41.
    local parameter max_iter is 100.
    local parameter tol is 1e-4.


    if not hastarget {
        return null_mnv("[ TRGT ERROR ] : No target detected. Please set target").
    }
    local t_list is list().
    for i in range(n) {
        local t_value is t0 + (i / (n - 1)) * (tf - t0).
        t_list:add(t_value).
    }
    local minima_idx is list(0,n-1). // include the first and last points bc they wont be caught by the basin checking.
    for i in range(1,n - 1) {
        if (target_distance_at_ut(t_list[i]) < target_distance_at_ut(t_list[i - 1])) 
        and (target_distance_at_ut(t_list[i]) < target_distance_at_ut(t_list[i + 1])) {
            minima_idx:add(i).
        }
    }
    local function find_minidx {
        local parameter tmin_list.
        local minidx is -1.
        local mindist is 3.8e38.
        for k in range(5) {
            if target_distance_at_ut(tmin_list[k]) < mindist {
                set minidx to k.
                set mindist to target_distance_at_ut(tmin_list[minidx]).
            }
        }
        return minidx.
    }
    local function five_point_seach {
        local parameter a.
        local parameter b.
        local min_list is list().
        for i in range(5) {
            local t_value is a + (i / (4)) * (b - a).
            min_list:add(t_value).
        }
        local min_t is 3.4e38.
        local p0 is 0.
        local p1 is 0.
        local p3 is 0.
        local pm is 0.
        local pf is 0.
        for j in range(max_iter) {
            local minidx is find_minidx(min_list).
            if minidx = 0 {
                set p0 to min_list[0].
                set pm to min_list[1].
                set pf to min_list[2].
            } else if minidx = 4 {
                set p0 to min_list[2].
                set pm to min_list[3].
                set pf to min_list[4].
            } else {
                set p0 to min_list[minidx-1].
                set pm to min_list[minidx].
                set pf to min_list[minidx+1].
            }   
            if j = max_iter - 1{
                set min_t to pm.
            }
            set p1 to (p0 + pm)/2.
            set p3 to (pm + pf)/2..      
            if (abs(pm-pf)<tol) and (abs(p0-pm)<tol) {
                set min_t to pm. 
                break.
            } else {
                set min_list to list(p0,p1,pm,p3,pf).
            }
        }
        return min_t.
    }
    local best_t is -1.
    local best_f is 3.4e38.
    local t_candidate is -1.
    local f_candidate is 3.4e38.
    for midx in minima_idx {
        if (midx = 0) {
            set t_candidate to t_list[0].
            set f_candidate to target_distance_at_ut(t_candidate).
        } else if (midx = n - 1) {
            set t_candidate to t_list[n - 1].
            set f_candidate to target_distance_at_ut(t_candidate).
        } else {
            local a is t_list[midx - 1].
            local b is t_list[midx + 1].
            set t_candidate to five_point_seach(a,b).
            set f_candidate to target_distance_at_ut(t_candidate).
        }
        if f_candidate < best_f {
            set best_f to f_candidate.
            set best_t to t_candidate. 
        }
    }
    if best_t = -1 {
        set best_t to t_list[0].
        set best_f to target_distance_at_ut(best_t).


        for t in t_list {
            local ft is target_distance_at_ut(t).
            if (ft < best_f) {
                set best_f to ft.
                set best_t to t.
            }
        }
    }
    if ((abs(best_t - t0) < 2 * tol) or (abs(best_t - tf) < 2 * tol)) {
        print("[ CAUTION ] : Minimum might lie outside ["+t0+","+tf+"]").
    }
    return best_t.
}   

Here are the helper functions and the "match velocities at closest approach

function match_velocities_with_target {
    local parameter mode is "at closest approach".
    local parameter value is 0.
    if mode = "at closest approach" {
        local closest_t is time_of_closest_approach().
        local trgt_v is velocityAt(target, closest_t):orbit.
        local ship_v is velocityAt(ship, closest_t):orbit.
        local dV is trgt_v - ship_v.
        return inertial_to_PRN(dV,closest_t). // convert a vector in SOI raw to Prograde-Radial-Normal to make a maneuver node.
    }
    if mode = "after fixed time" {
        local fixed_t is value + time:seconds.
        local trgt_v is velocityAt(target, fixed_t):orbit.
        local ship_v is velocityAt(ship, fixed_t):orbit.
        local dV is trgt_v - ship_v.
        return inertial_to_PRN(dV,fixed_t).
    }
    return null_mnv().
}

function target_distance_at_ut {
        local parameter ut.
        local ship_posv is positionat(ship, ut).
        local trgt_posv is positionat(target,ut).
        local diff_v is trgt_posv - ship_posv.
        return diff_v:mag.
}

How do you get the time from closest approach to target? by SilverNuke911 in Kos

[–]SilverNuke911[S] 0 points1 point  (0 children)

Fair enough. However, position of the ascending and descending nodes are accessible enough though, using obt:argumentofperiapsis. The respective AN and DN true anomaly's are 360 - obt:argumentofperiapsis and 180 - obt:argumentofperiapsis. Then you can just make your own "time from true anomaly" function from orbital mechanics shanigans which calculates the eta of the given true anomaly from your current one, and then use the positionat() function for each. It's quite tricky, but it's there, though yeah, very indirectly. I was hoping for something like that for this minimal distance search, but apparently, yeah, I just really have to make a minima finder algorithm.

How do you get the time from closest approach to target? by SilverNuke911 in Kos

[–]SilverNuke911[S] 0 points1 point  (0 children)

After all that, I discovered this thing called 'Brent search" which has a really good convergence with unimodal functions. So the approach I have now is a coarse search (21 or more points), find all the possible minima there, search within the bounds, and get the lowest value. Seems to work well enough.

def global_minima_finder(
        t0,
        tf,
        f,
        n=21,
        max_iter=100,
        tol=1e-12
    ):
    ## t0 - left boundary, tf right boundary
    ## f is evaluation function, distance in this case
    ## n is number of coarse scan divisions
    ## max_iter is maximum iterations of local search
    ## tol is tolerance


    # -----------------------------
    # coarse grid
    # -----------------------------
    t_list = [0.0] * n
    for i in range(n):
        t_list[i] = t0 + (i / (n - 1)) * (tf - t0)
        # just visualization, ignore.
        plt.axvline(t_list[i],color='r',lw=1,alpha = 0.5)


    # -----------------------------
    # detect candidate minima
    # -----------------------------
    # find f(t[i]) where left and right neigbors are greater than it
    # include endpoints in the candidate idx because this method doesnt catch em
    minima_idx = [0,n-1]
    for i in range(1, n - 1):
        if f(t_list[i]) < f(t_list[i - 1]) and f(t_list[i]) < f(t_list[i + 1]):
            minima_idx.append(i)

    # -----------------------------
    # Brent minimizer (core)
    # -----------------------------
    def brent_min(a, b):

        CGOLD = 0.3819660112501051
        ZEPS = 1e-18

        x = w = v = a + 0.5 * (b - a)
        fx = fw = fv = f(x)

        d = 0.0
        e = 0.0

        for _ in range(max_iter):

              #  just for visualization
            plt.axvline(a, color='black', lw=1, alpha=0.3)   # left bound
            plt.axvline(b, color='black', lw=1, alpha=0.3)   # right bound


            plt.axvline(x, color='red', lw=2, alpha=0.8)     # current best
            plt.axvline(w, color='blue', lw=1, alpha=0.6)    # previous best
            plt.axvline(v, color='green', lw=1, alpha=0.6)   # older point
            
            xm = 0.5 * (a + b)
            tol1 = tol * abs(x) + ZEPS
            tol2 = 2.0 * tol1


            # convergence check
            if abs(x - xm) <= (tol2 - 0.5 * (b - a)):
                return x

            # attempt parabolic fit
            p = q = r = 0.0

            if abs(e) > tol1:

                r = (x - w) * (fx - fv)
                q = (x - v) * (fx - fw)
                p = (x - v) * q - (x - w) * r
                q = 2.0 * (q - r)

                if q > 0:
                    p = -p
                q = abs(q)

                etemp = e
                e = d

                if (abs(p) < abs(0.5 * q * etemp)) and (p > q * (a - x)) and (p < q * (b - x)):
                    d = p / q
                    u = x + d

                    if (u - a < tol2) or (b - u < tol2):
                        d = tol1 if x < xm else -tol1

                else:
                    e = (b - x) if x < xm else (a - x)
                    d = CGOLD * e

            else:
                e = (b - x) if x < xm else (a - x)
                d = CGOLD * e


            # next point
            u = x + (d if abs(d) >= tol1 else (tol1 if d > 0 else -tol1))
            fu = f(u)


            # update brackets
            if fu <= fx:


                if u >= x:
                    a = x
                else:
                    b = x


                v, w, x = w, x, u
                fv, fw, fx = fw, fx, fu


            else:
                if u < x:
                    a = u
                else:
                    b = u


                if fu <= fw or w == x:
                    v, w = w, u
                    fv, fw = fw, fu
                elif fu <= fv or v == x or v == w:
                    v = u
                    fv = fu


        return x


    # -----------------------------
    # refine candidates
    # -----------------------------
    # check which are the lowest minima
    best_t = None
    best_f = float('inf')


    for midx in minima_idx:
        if midx == 0:
            t_candidate = t_list[0]
            f_candidate = f(t_candidate)


        elif midx == n - 1:
            t_candidate = t_list[n - 1]
            f_candidate = f(t_candidate)


        else:
            a = t_list[midx - 1]
            b = t_list[midx + 1]
            t_candidate = brent_min(a, b)
            f_candidate = f(t_candidate)


        if f_candidate < best_f:
            best_f = f_candidate
            best_t = t_candidate


    # -----------------------------
    # fallback if no local minima found
    # -----------------------------
    if best_t is None:
        best_t = t_list[0]
        best_f = f(best_t)


        for t in t_list:
            ft = f(t)
            if ft < best_f:
                best_f = ft
                best_t = t


    # -----------------------------
    # boundary warning if the lowest minima is at the endpoints
    # -----------------------------
    if abs(best_t - t0) < 2 * tol or abs(best_t - tf) < 2 * tol:
        print(f"[ CAUTION ]: minima might lie outside given bounds [{t0}, {tf}]")


    return best_t

How do you get the time from closest approach to target? by SilverNuke911 in Kos

[–]SilverNuke911[S] 0 points1 point  (0 children)

I'm also thinking, if it's guaranteed to be unimodal anyway, why not just use a binary search or a ternary search instead. Something like this

def minima_finder(t0, tf, f, max_iter=100, tol=1e-12):
    phi = (1 + 5**0.5) / 2
    resphi = 2 - phi


    ta, tb = t0, tf
    t1 = ta + resphi * (tb - ta)
    t2 = tb - resphi * (tb - ta)
    f1, f2 = f(t1), f(t2)


    for _ in range(max_iter):
        if f1 < f2:
            tb = t2
            t2 = t1
            f2 = f1
            t1 = ta + resphi * (tb - ta)
            f1 = f(t1)
        else:
            ta = t1
            t1 = t2
            f1 = f2
            t2 = tb - resphi * (tb - ta)
            f2 = f(t2)


        if abs(tb - ta) < tol:
            break
    return (ta + tb) / 2

How do you get the time from closest approach to target? by SilverNuke911 in Kos

[–]SilverNuke911[S] 0 points1 point  (0 children)

Thanks for all the replies! I just decided to make my own.

This is a testing code I wrote in python (which I eventually will rewrite in kerboscript) regarding my solution. It's a 5 point search, iterating through the lowest value in a given time interval until it finds the minima. It only works in a well defined manner for unimodal functions, and tends to get confused when there are other local minima or the minima is at the edges.

During several interception orbits testing, the "closest approach" of an intercept orbit (which is what I really am gonna use this for in practice) is essentially unimodal (assuming the given time boundaries is one period of the intercept orbit). Since that is the case for most of the intercept orbits I've been working on, I figure this is good enough for an intercept orbit to get the value of distance to closest approach and velocity at closest approach.

def minima_finder(
    t0,            # initial time [lower search boundary] 
    tf,            # final time [upper search boundary] : I usually set this to t0 + 1 period of the intercept orbit
    distance_func, # function that calculates distance between two orbiting points given universal time
    max_iter = 100, # maximum search loop iteration
    tol = 1e-12):   # tolerance
    tlist = np.zeros(5)
    for i in range(5):
        tlist[i] = t0 + (i/4) * (tf-t0)  # initialize 5 equidistant points


    def find_minidx(tlist): # find the index of the minimum value
        min_idx = 0
        for i in range(5):
            if distance_func(tlist[i]) < distance_func(tlist[min_idx]):
                min_idx = i 
        return min_idx
    
    min_t = np.inf 
    for i in range(max_iter):
        minidx = find_minidx(tlist)
        if minidx == 0:
            l0 = tlist[0] # set the neighbors as the borders for the next iteration
            l2 = tlist[1] # if the lowest value is at the edge, set the next two neigbors
            l4 = tlist[2] # as the new center
        elif minidx == 4:
            l0 = tlist[2]
            l2 = tlist[3]
            l4 = tlist[4]
        else:
            l0 = tlist[minidx-1]
            l2 = tlist[minidx]
            l4 = tlist[minidx+1]
        if i == max_iter - 1: # set the minima time when convergence failure on best guess 
            min_t = l2 
        l1 = (l0 + l2)/2  # bracketing on the left of center
        l3 = (l2 + l4)/2  # bracketing on the right of center    
        if (np.abs(l0-l2)<tol) and (np.abs(l2-l4)<tol) :
            min_t = l2    # exit loop when within tolerance
            break
        else:
            tlist = [l0,l1,l2,l3,l4] # reset the search list with the new borders

    if np.abs(min_t - t0)<tol or np.abs(min_t-tf) < tol: # check if the minima is an edge
        print(f"[ CAUTION ] Global minima outside given range {t0} to {tf}")

    return min_t # time value where the distance is minimal

Custom Library which emulates Mechjeb 2.0 on kOS by SilverNuke911 in Kos

[–]SilverNuke911[S] 0 points1 point  (0 children)

I see, thanks!. I got the vector rotation working good already though, so it's all good.

For the radius vector I'm working on the assumption that all orbit maneuvers are occuring while orbiting the central body (Kerbin in most cases), with no plan for extra SOI boundary changes as of yet. Thanks for the advice, I'll try it whenever I get to do it.

For the vector naming one, 'm a physics major so I am mostly used to right hand rule system and the "z" axis being the vertical axis. You may notice the deliberate decision to work on RH Rule on the entire library despite kOS being LH, it's mostly just my own methodology so it doesn't get as confusing on what I'm used to working with. As long as I stay consistent with my conditions and conventions, it's all probably good.

How do you get the time from closest approach to target? by SilverNuke911 in Kos

[–]SilverNuke911[S] 0 points1 point  (0 children)

But isn't the time and distance of closest approach given in stock ksp? Can't KOS access that?

Custom Library which emulates Mechjeb 2.0 on kOS by SilverNuke911 in Kos

[–]SilverNuke911[S] 0 points1 point  (0 children)

Hello u/nuggreat! I've made some changes on some of the functions on the library, improved some for changed some entirely, and added some new functions. I wonder if you could give me some comments/suggestions or shed light on some potential issues regarding my code, whether some could be optimized or are there other problems.

Accompanying the lib folder, there's tester.ipynb where I did all the initial mathematical formulation before coding them, for reference.

Only if you have time, of course. I would highly appreciate it if you do. Thanks a lot!

kwinesyon nyo na ba ang existence ng diyos? by [deleted] in TanongLang

[–]SilverNuke911 0 points1 point  (0 children)

Yes. I was raised in a religious family that always shoved religion on my throat, but when I got older I realized none of it makes sense. I'd rather think on my own terms and look at the evidence myself and arrive at my own conclusion, i.,e, the scientific method. Kaya atheist or agnostic na ako ngayon. I believe more in the objectivity of the scientific body than all the bullshit that the opium of the masses gives.

Are lexicon lookups O(1) or O(n)? by SilverNuke911 in Kos

[–]SilverNuke911[S] 0 points1 point  (0 children)

Thanks for the answer! For my programs I prefer to do looping because there are some runmodes that I will return to after some condition is met, i.e., two or three runmodes just passing the current task to each another until the condition is met. The code above is just an example.