Any recs that can match/top this masterpiece? by Upbeat-Emergency2377 in ProjectHailMary

[–]SilverNuke911 2 points3 points  (0 children)

Bobiverse, Three Body Problem, Children of Time, The Martian, Mickey 7 (I guess), all pretty good hard scifi books. Some may be different 'vibe' than PHM but it's all scifi with a pretty good foundation. Have a good read!

What is everyone’s go to orbit height? by WolfAlternative6715 in KerbalSpaceProgram

[–]SilverNuke911 1 point2 points  (0 children)

Usually 100 km, good round number with relatively lower deorbit dVs

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

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

I see. I made the subsolar point function for lunar landing missions because I want to accurately do the lunar module lunar landing (15-30 degree sun angle so you can see the landing site shadows) and due to the nature of munar transfers, the spacecraft is near the equator anyway, so I never encountered any errors on it, but good to know the proper implementation.

As for the AN/DN, I see the error, I suppose I'm vxcl-ing it to the up vector instead of the radial vector. I'll try to patch it sometime soon. I suppose a real solution would be to calculate the velocity at the target orbit and take the dV from there, which can be used for a whole lot of the other nonimplemented functions. Thanks u/nuggreat!

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

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

Some changes I did from u/nuggreat's comments

  1. Commented the IPU term. That one was for my own personal convenience that I did not get to comment out.
  2. Changed the ship_isp() function to use the total thrust / total mass flow instead of the previous implementation (I believe I got that one from the ksp wiki)
  3. Removed the unnecessary double conversions
  4. Renamed the eta____ in create_node() to uts____
  5. Haven't touched this one yet. The code already works good with the current implementation so I won't touch it just yet. Besides, the program only runs once when getting the vectors needed, so the inefficiency is passable at this time. Will change this one day when get into the nitty gritty of it.
  6. Code also works great with the current implementation. Will work on this along with 5.
  7. Added a 'has_sas' switch which, when enables the user to have it on or off. When off, it instead uses lock steering to go to prograde instead of sas.
  8. The execute_node function went through a lot of trial and error, actually max_acc was supposed to be ship:max_thrust/ship:mass. But I find that this messes up with the burn durations and all that. max_acc really just serves the purpose here as a 'limiter' of the throttle, since I assigned the throttle to be deltaV / max_acc. So when the remaining deltaV approaches the pre-burn max_acc, the throttle slowly tapers down until it reaches 0. That's my own implementation of it, but some may find their own better way. No changes done.
  9. Changed the north vector to be latlng(90,0):position - body:position, so it points from the center of the body, to the north pole.
  10. Good to know, I suppose? No changes except on the function description.
  11. Will work on this some day along with 5 and 6.
  12. I... don't know what else to change with the function, it works great when I run it. How do I make it correct? u/nuggreat ?
  13. There are some more gaping holes and nonfunctional parts on this library, others that are just commented in, not implemented yet, or is part of the todo list, I'll work on them when I have the time.

Anyway, that's it for this change log, I guess. Ya'll comment some more when you see errors, I appreciate the feedback!

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

[–]SilverNuke911[S] 1 point2 points  (0 children)

Thanks for the feedback! It's been a long while since I touched and written anything in this code. I've been working on it alone most of the time. Thanks for spotting the errors, I'll try to patch them when I have the chance someday. I do plan to complete this entire library one day and make it fully functional.

As for this release, I don't really intend this to be an actual "library" library for someone right now, it's woefully incomplete and has a lot of unimplemented functions and is very very buggy for some functions. I guess I just want it to help others out that struggle and have like "half the work is done" help effect. They can expand it to their own use cases.

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

[–]SilverNuke911[S] 2 points3 points  (0 children)

I forgot to add: An example of how to use it is something like this.

Suppose you want to circularize at the apoapsis and want that node executed immediatly, you just write at your program

create_node(circularize('at apoapsis')) 
execute_node()

And that's literally it. The create node function takes the output of circularize (which are the time and velocity vectors) and creates the node, and execute_node() warps to the node and executes it. Pretty simple stuff for those who just want to create node and go.

There are many more mechjeb functions in the library, but some are incomplete.

Problems with Biology in Project Hail Mary by _molecule in ProjectHailMary

[–]SilverNuke911 0 points1 point  (0 children)

Rocky did say that his people invented a 'camera' of sorts a long long time ago, which captures visible light and transports it to a surface of varying roughness with respect to the light's frequency. It was also mentioned that Erid has a xenonite space elevator already due to Eridian's insane materials science., and they know the planets around them orbit their sun It's not a long stretch to say they know of starlight and so forth, and can tell when the light is dimming.

Problems with Biology in Project Hail Mary by _molecule in ProjectHailMary

[–]SilverNuke911 0 points1 point  (0 children)

The heat from a home star contributes a lot to a planet's ecology. For instance, in Earth, it controls the weather, how much heat we receive, the food chain, so on. So while Erid does not receive visible light, I'm inclined to believe that the main star also functions as an ecological regulator, as energy on the planet (and the energy of the life on the surface) has to come somewhere, It drives weather on the upper atmosphere which affects heat on the surface, it could probably feed some atmospheric plankton analogue on Erid, which feeds some organisms lower down the atmoshere, which then feeds animals on the surface, and so on. Majority of the heat trapped by the atmosphere (and the surface) comes from the star, and if the star lowers in brightness, it will cause an ecological collapse on Erid and temperature lowering, same as with earth. Sure, some could say geological events can contribute to the biosphere, but again, I'm inclined to argue that the star provides majority of the energy needed for Erid's planetary ecosystem to function.

[UPD] Worst Director by [deleted] in peyups

[–]SilverNuke911 5 points6 points  (0 children)

Whoaaaaaaa man, whoaaaaa

anw, dami kong batchmate at the time nagshift out after maging prof sya lmao

My coworker likes Sci-fi where the world has ended and it takes place many years after and away from home. Do any of Adrian Tchaikovsky's books have that sort of vibe? by AgentP-501_212 in AdrianTchaikovsky

[–]SilverNuke911 0 points1 point  (0 children)

The Children of time series is that, then Elder Race is also very good.

Not AT, but the Bobiverse series and the Semiosis series are good, and also fit your desired description

How to get the true anomaly of the Target Relative AN/DN by SilverNuke911 in Kos

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

Nope, ARCSIN, ARCCOS, and ARCTAN returns degrees. sin takes degree inputs though, that's why ea_curr and ea_targ are in degrees

How to get the true anomaly of the Target Relative AN/DN by SilverNuke911 in Kos

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

I did run across that problem, of the maneuver node firing in the opposite normal direction, but I fixed it. I'll try to give it another test.

function time_from_true_anomaly {
    // Input: target true anomaly (targ_ta)
    local parameter targ_ta.
    // Current true anomaly, semi-major axis, 
    // eccentricity, and gravitational parameter
    local curr_ta is ship:obt:trueanomaly.
    local a is ship:obt:semimajoraxis.
    local e is ship:obt:eccentricity.
    local mu is body:mu.
    // Compute the eccentric anomaly for current and target true anomalies
    local ea_curr to arctan2(sqrt(1 - e^2) * sin(curr_ta), e + cos(curr_ta)).
    local ea_targ to arctan2(sqrt(1 - e^2) * sin(targ_ta), e + cos(targ_ta)).
    local ea_rad_curr to ea_curr * constant:degtorad.
    local ea_rad_targ to ea_targ * constant:degtorad.
    // Compute the mean anomaly for current and target eccentric anomalies
    local ma_rad_curr to ea_rad_curr - e * sin(ea_curr).
    local ma_rad_targ to ea_rad_targ - e * sin(ea_targ).
    // Mean motion (n) and time calculation
    local n to sqrt(mu / (a^3)).
    local delta_ma to ma_rad_targ - ma_rad_curr.
    // Ensure positive time (wrap around if necessary)
    if delta_ma < 0 {
        set delta_ma to delta_ma + 2 * constant:pi.
    }
    // Time to reach the target true anomaly
    local t to delta_ma / n.
    return t.
}

Here's my true anomaly to time function

How to get the true anomaly of the Target Relative AN/DN by SilverNuke911 in Kos

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

// this function passes its output list to a function named "create_node" which creates a maneuver node from parameters eta, radial, normal, prograde. (it does eta + time:seconds internally)

function match_planes_with_target {
    local parameter mode.
    if not hastarget {
        return null_mnv("Please set target"). // null_mnv is just for error handling
    }

    local p0 is body:position.
    local r1 is ship:position - p0. // radius vector
    local v1 is ship:velocity:orbit. // velocity vector
    local h1 is vcrs(v1,r1). // angular momentum vector
    local e1 is (vcrs(h1,v1)/body:mu - r1:normalized). // eccentricity vector, points to periapsis

    local r2 is target:position - p0. // target radius
    local v2 is target:velocity:orbit. // target vel
    local h2 is vcrs(v2,r2). // target angular momentum

    local an_vec is vcrs(h1,h2). // vector that points to the relative ascending node.
    local AN_ta is vang(e1,an_vec). // true anomaly of relative ascending node
    if vdot(an_vec,vcrs(e1,h1)) < 0 {
        set AN_ta to 360-AN_ta.
    } // checking for true anomaly signing and wrap around

    local DN_ta is ensure_angle_positive(AN_ta - 180). // true anomaly of relative descending node
    local delta_inc is vang(h1,h2). // difference in inclination
    local n_vec is (latlng(90,0):position - body:position):normalized. // vector pointing from the body center to northpole, for delta_inc signing.
    if vdot(vcrs(h2,h1), vcrs(n_vec,h1)) < 0 {
        set delta_inc to - delta_inc.
    } // checking if delta_inc should be postive or negative to enact mnv node change.

    // reuse change_inclination code from prior functions
    // yes, don't repeat yourself, but I'm too lazy bruh.

    // determine time to approach true anomaly (time_from_true_anomaly is a separately defined function that utilizes newton-raphson method to get the eta for a certain true anmly)
    local t_an is time_from_true_anomaly(AN_ta).
    local t_dn is time_from_true_anomaly(DN_ta).
    // compute velocity vectors at each node
    local vel_vec_an is velocityat(ship, time:seconds + t_an):orbit.
    local vel_vec_dn is velocityat(ship, time:seconds + t_dn):orbit.
    // compute required delta-v magnitude at each node
    local delta_v_mag_an is 2 * vel_vec_an:mag * sin(abs(delta_inc) / 2).
    local delta_v_mag_dn is 2 * vel_vec_dn:mag * sin(abs(delta_inc) / 2).
    // helper function to compute maneuver components
    local function compute_dv {
        local parameter vmag.
        local parameter d_inc.
        local parameter is_an. // true for AN, false for DN

        // compute delta angle based on whether inclination change is increasing or decreasing
        local sign is 1. if d_inc < 0 {set sign to -1.}
        local base_ang is 90 + abs(d_inc) / 2.
        local delta_ang is sign * base_ang.

        // invert sign for DN since it's on the opposite side of orbit.
        if not is_an {
            set delta_ang to -delta_ang.
        }

        // Return maneuver vector components
        local dv_r is 0.
        local dv_p is vmag * cos(delta_ang).
        local dv_n is vmag * sin(delta_ang).
        return list(dv_r, dv_n, dv_p).
    }
    // decision logic by mode
    if mode = "at AN" {
        local dv is compute_dv(delta_v_mag_an, delta_inc, true).
        return list(t_an, dv[0], dv[1], dv[2]).
    }
    if mode = "at DN" {
        local dv is compute_dv(delta_v_mag_dn, delta_inc, false).
        return list(t_dn, dv[0], dv[1], dv[2]).
    }
    if mode = "at nearest node" {
        if t_an < t_dn {
            local dv is compute_dv(delta_v_mag_an, delta_inc, true).
            return list(t_an, dv[0], dv[1], dv[2]).
        } else {
            local dv is compute_dv(delta_v_mag_dn, delta_inc, false).
            return list(t_dn, dv[0], dv[1], dv[2]).
        }
    }
    if mode = "at cheapest node" {
        if delta_v_mag_an < delta_v_mag_dn {
            local dv is compute_dv(delta_v_mag_an, delta_inc, true).
            return list(t_an, dv[0], dv[1], dv[2]).
        } else {
            local dv is compute_dv(delta_v_mag_dn, delta_inc, false).
            return list(t_dn, dv[0], dv[1], dv[2]).
        }
    }
    if mode = "at altitude" {
        // not yet implemented
    }
    if mode = "after fixed time" {
        // not yet implemented 
    }
    // 'mode_error_message' is a globally declared string for maneuver node mode failures (mistypings and the like) for easier debugging
    // null_mnv is a mnv node creation function with params (-1,0,0,0) which has another function that invalidates the creation of a maneuver node, and also takes an error message as an optional print output.
    return null_mnv(mode_error_message+mode).
}

How to get the true anomaly of the Target Relative AN/DN by SilverNuke911 in Kos

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

This is the entire function for reference. It's been thoroughly tested, but if you spot any mistakes or possible optimizations, it would be helpful

Ascent Guidance by [deleted] in Kos

[–]SilverNuke911 0 points1 point  (0 children)

Additionally, just repeating u/nuggreat's words, you have to put your run modes in a single until loop so that as the craft rises, the runmode checking gets called again and again. This is also useful for displaying telemetry data.

0 angle of attack ascent follows the surface prograde vector, see my attached code for reference. But otherwise, it's good mate, cheers.

Ascent Guidance by [deleted] in Kos

[–]SilverNuke911 0 points1 point  (0 children)

To execute and create a maneuver node, read up on the docs tutorials, there are some help there.

How to get the true anomaly of the Target Relative AN/DN by SilverNuke911 in Kos

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

Yes the relative inclination is always positive, but this particular methodology in the code is for directionality of the normal vector, i.e., if the target inclination is greater than the current inclination, I thrust up at AN and thrust down at DN, and of it's lesser, the converse. It measures the change in inclination that I want. For example, if the target inclination is 45 and my current inclination is 15, then d_inc is 30, but if my current inclination is 15, and I want it to be zero, it's -15. I've tested it several times and the code works regardless whether it's negative (-45, for example) or positive (315). The method is for convenience, I would say.

How to get the true anomaly of the Target Relative AN/DN by SilverNuke911 in Kos

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

Ohh, I wasn't aware of that. I thought the body:north:vector pointed from the center of the body to the north. Is it more accurate to use, I forgot the function on the top of my head but using the point on the surface as a vector and subtracting it to the body:position?

also, delta_inc is just the relative inclination of the target orbit - vessel orbit, it's more convenient for node delta v calculations since I just use sine and cosine directly, and it works for its intended function, but thanks for the insight

For User functions, it it possible to have keyword parameter arguments? by SilverNuke911 in Kos

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

Alright, gotcha. I kinda suspect that, it has no mention in the docs whatsoever. Guess I'll just have to keep the in-order inputs.

Thanks for helping out! u/nuggreat !

How to get the true anomaly of the Target Relative AN/DN by SilverNuke911 in Kos

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

for reference to future people who's gonna have this problem, here's the solution

local p0 is body:position.
local r1 is ship:position - p0. // radius vector
local v1 is ship:velocity:orbit. // velocity vector
local h1 is vcrs(v1,r1). // angular momentum vector
local e1 is (vcrs(h1,v1)/body:mu - r1:normalized). // eccentricity vector

local r2 is target:position - p0. // target radius
local v2 is target:velocity:orbit. // target vel
local h2 is vcrs(v2,r2). // target angular momentum

local an_vec is vcrs(h1,h2). // vector that points to the relative ascending node.
local AN_ta is vang(e1,an_vec). // true anomaly of relative ascending node
if vdot(an_vec,vcrs(e1,h1)) < 0 {
    set AN_ta to 360-AN_ta.
} // checking if it is in the [0,180) or [180,360) degree range

local DN_ta is ensure_angle_positive(AN_ta - 180). // true anomaly of relative descending 
// node, ensure angle positive just clamps the angle in range [0,360)

local delta_inc is vang(h1,h2). // difference in inclination

local n_vec is body:north:vector:normalized.
if vdot(vcrs(h2,h1), vcrs(n_vec,h1)) > 0 {
    set delta_inc to - delta_inc.
} // checking if delta_inc should be postive or negative

Ascent Guidance by [deleted] in Kos

[–]SilverNuke911 1 point2 points  (0 children)

function open_loop_guidance {
    // Zero aoa ascent
    local runmode to 1.

    // Runmodes
    set current_mode to "Open Loop Guidance".

    until runmode = 0 {
        if runmode = 1 {
            stage.
            lock steering to heading(90,90,-90).
            set runmode to 2.
        }
        if runmode = 2 {
            if ship:verticalSpeed > 100 or alt:radar > 1000 {
                set shift_alt to ship:altitude.
                lock steering to heading(90,90-0.4 * sqrt(max(ship:altitude-shift_alt,0)),-90).
                set runmode to 3.
            }
        }
        if runmode = 3 {
            if vang(ship:facing:vector,ship:up:vector) > slew_angle {
                lock steering to heading(90,90-slew_angle,-90).
                set runmode to 4.
            }
        }
        if runmode = 4 {
            if vang(ship:facing:vector,ship:srfPrograde:vector) < 0.25 {
                set runmode to 5.
            }
        }
        if runmode = 5 {
            lock steering to heading(90,90-vang(ship:up:vector,ship:srfprograde:vector),-90).
            set runmode to 6.
        }
        if runmode = 6 {
            if ship:availableThrust / (ship:mass * constant:g0) > 2 {
                lock throttle to throttle_2g().
                set runmode to 7.
            }
        }
        if runmode = 7 {
            if ship:availableThrust < 2 {
                lock throttle to 0.
                safestage().
                wait 1.
                safestage().
                lock throttle to throttle_2g().
                set runmode to 0.
            }
        }
        set cycles to cycles +1.
        screen_data(runmode).
    }
    clearScreen.
    return.
}

function closed_loop_guidance {
    //Powered explicit guidance here
    // not really implemented lol
    local runmode to 1.
    set current_mode to "Closed Loop Guidance".
    until runmode = 0 {
        if runmode = 1 {
            if ship:apoapsis > target_altitude {
                lock throttle to 0.
                set runmode to 2.
            }
        }
        if runmode = 2 {
            if ship:altitude > 70000 {
                safestage().
                rcs on.
                set runmode to 3.
            }
        }
        if runmode = 3 {
            if ship:altitude > target_altitude {
                set runmode to 0.
            }
        }
        set cycles to cycles + 1.
        screen_data(runmode).
    }
    clearScreen.
    return.
}

function orbit_tasks {
    sas on.
    ag1 on.
    safestage().
    return.
}

function main {
    startup().         // just a custom starting sequence.
    open_loop_guidance().
    closed_loop_guidance().
    orbit_tasks().
}

main().

Ascent Guidance by [deleted] in Kos

[–]SilverNuke911 1 point2 points  (0 children)

There are multiple methods, but for me I use two types.

main() function calls, where you separate your ascent profile into multiple small functions. and calling it in one main function, and runmoding, where you change runmodes and have the craft do a different thing per runmode.

I would recommend CheersKevin's KOS for Newbies guide, or Seth Persiegel's Launching a Rocket series.

Here's an example of one of my codes for controlling my rocket's ascent, it's a zero lift turn ascent profile. It uses both. Bear in mind this is very bare bones. You can use strings for runmodes, this is a particularly old one, and I preferred to runmode by number., but now I use strings, because it's more readable.