Jump to content

[1.12.x] Kerbulator: use your own math!


wmvanvliet

Recommended Posts

just wanna stop in and say again that this mod is really awesome and I hope the author has some time to give it some attention again at some point! So great for saving and running all the various equations I come across while learning more about space flight

Link to comment
Share on other sites

  • 2 weeks later...
  • 5 months later...
  • 2 weeks later...
  • 2 weeks later...
  • 5 weeks later...
  • 3 weeks later...

Version 0.4 is here!

I've added some things to the language. By popular demand, you can now have if-statements. Although in math, you call them piecewise functions. They go like this:

x = 2
y ={ x + 1, if 0 ≤ x < 2
         0, otherwise

that would in this case set y to 0, since x is not smaller than 2. Check the language reference for more information.

This means there is also a bunch of boolean operators added to the language (< > ≤ ≥ == ≠ and more).
Note that these operators obey the rules of mathematical notation, not necessarily programming languages, by which I mean this:

0 ≤ x < 2 < y ≤ 5

means 'x bigger than 0 (inclusive) and smaller than 2 (exclusive) and y bigger than 2 (exclusive) and smaller than 5 (inclusive)'.

Another nice feature I added is that you can specify pre- and postfixes for your output variables. This makes them look nicer in the GUI. For example:

out: "inclination: " inc "°" "Inclination of current orbit"
inc = Craft.Inc

will display in the GUI when you run the function something like:

inclination: 0.45°

Again, see the language reference for the updated syntax.

Link to comment
Share on other sites

I just noticed that the arrow keys are broken in text fields provided by mods. This is not limited to Kerbulator, but all text fields. That's really annoying and I will look for a workaround. In the meanwhile, I suggest using an external editor for any major editing of your Kerbulator functions (see the manual on how to do this).

On the off chance you use vim as editor, I got a syntax highlighting file for you.

Link to comment
Share on other sites

  • 1 month later...

I just found your mod, and installed it immediately! Really nice work.
This is very handy to calculate resonant orbits for remotetech satellite constellations.

However i missed a feature (maybe i just overlooked it):

After running a function i would like to use the result in another function, by entering the variable name in the new function. 
Say for example i have a function GetSemimajorAxis. It's output is called "a". I run the function by hitting the run button and get the
result. Now i have a function GetSpeedAtPeriapsis. It requires the semimajor axis, so i just want to hit the run button, and enter the
variable name "a". But i can only have one open window for the functions, so the previous result is discarded. Remembering the
value is not that comfortable. 

It would be really nice if the window just sticks around until i close it, and i could use the output values as inputs, but without nesting
the functions, just by chaining them by hand.

Link to comment
Share on other sites

What do you mean exactly by 'nesting the functions'?

Anyway, there are a couple of solutions for the thing you want to achieve:

1. Make the GetSpeedAtPeriapsis function call the GetSemimajorAxis function:

in: Ap
in: Pe
in: mu
out: v

a = GetSemimajorAxis(Ap, Pe)
v = sqrt(mu * (2/Pe - 1/a))

(perhaps that is what you mean by nesting the functions)

2. You can do function calls inside the input fields of the Run dialog: run the GetSpeedAtPeriapsis function you have, but enter GetSemimajorAxis(<some Ap>, <some Pe>) into the 'a' field (replace <some Ap> and <some Pe> with actual numeric values or globals like Craft.Ap + Parent.R)

As far as keeping the window open, you can always click the 'repeated run' button (the play icon with arrows). It will use up CPU as it keeps evaluating the function over and over again, but the window will stay open :) 

Edited by wmvanvliet
Link to comment
Share on other sites

On 12.8.2016 at 0:09 PM, wmvanvliet said:

 

What do you mean exactly by 'nesting the functions'?

 

I want to use the result of one function for the next one. I am aware that you can call functions within functions, but to do so you have to
know in advance what you want to calculate.

On some missions, i need to improvise or i dont want to plan too many steps ahead. Let my give you an example of the use cases:

Lets say you have functions for the basic equations (vis viva and orbital period). For each function you have variations solved
for each variable. For example one version of visviva gives you the speed based on altitude and sma. Another one gives you
the altitude based on speed and sma. And you do this for each possible variable for each equation. This gives these 5 equations:

1) speed = f(altitude, sma)
2) altitude = f(speed, sma)
3) sma = f(speed, altitude)
4) period = f(sma)
5) sma = f(period)

Also you make some helper functions to convert between sma and ap+pe representation (using the Parent.R global for convenience)

6) sma = f(ap, pe)
7) ap = f(sma, pe)
8) pe = f(sma, ap)

Now you can combine the functions like lego pieces. For example you are on a hyperbolic trajectory around a planet and want
to circularize at Pe. You now want to set up a node which does this for you. So you would calculate:
- your current sma using equation 3
- your speed at Pe using equation 1
- your desired sma by using equation 6 with f(pe, pe)
- your desired speed by using equation 1, this time with the desired sma
- the difference of these speeds gives you your burn delta-v
- and now you could create a node with that difference and with the time to Pe.

You could write a function for this. But i like to do it step by step (before finding kerbulator i used a hand held calculator for this).
A very convenient way of chaining these functions would be by storing their value in a global, or by making their result global
(some double naming issues might arise here).

Idealy you only have to click the run buttons for equation 3, 1, 6, 1 and fill in the values. You can already do so if you remember
the values, for example calc function 1, remember or write down the value, use that as input to function 3, etc. But it would be
nice if the kerbulator itself could store the values for you.

It's not helpful to write every possible combinations of functions in advance because there are so many combinations. Want
to circularize at Ap instead? Just call equation 6 but with f(Ap, Ap) instead of f(Pe, Pe).

On 12.8.2016 at 0:09 PM, wmvanvliet said:

2. You can do function calls inside the input fields of the Run dialog: run the GetSpeedAtPeriapsis function you have, but enter GetSemimajorAxis(<some Ap>, <some Pe>) into the 'a' field (replace <some Ap> and <some Pe> with actual numeric values or globals like Craft.Ap + Parent.R)

This is halfway there. You could write the use case above as:

SetUpNode(Eta.Pe, VisVivaSpeed(Craft.Pe + Parent.R, VisVivaSma(Navball.OrbitalSpeed, Craft.Alt)) - VisVivaSpeed(Craft.Pe + Parent.R, SmaFromApPe(Craft.Pe, Craft.Pe))

But this is not very elegant and error prone. Also you might decide mid calculation that, lets say for a phasing orbit, your Pe is too low so you could redo the first steps and choose
a better one. This would only be possible if you see the intermediate values. One big formula hides the details.

How to improve this:

When you click run on the function list, open the window for that function but dont close the last one, so you can have multible function windows open at once
(i dont mean the permanent running displays, i mean the window with the function inputs and outputs).
You give each window a name/title (to avoid naming issues and differentiate between sma from function 1 and sma from function 2), for example "func1", "func2", and so on

Now you can use the values of one window as input for another window. Back to our use case from above:

Run equation 3 from the function window. Enter Navball.OrbitSpeed and Craft.Alt as inputs. Hit run. Now you get your sma.
Now run equation 1. But this time, enter Craft.Pe and func1.sma. The kerbulator now uses the output of function 1 as input for function 2, with ease for the user.

Link to comment
Share on other sites

Hrm, but that would mean that Kerbulator spams your screen with windows you have to manually close every time you run a function. Handy for the use case you describe above, but a pain in other cases.

Also, what would happen when you need the output of a function twice? For example, you need the speed at Ap and at Pe and you want to use the visviva function to compute both.

Really what you want is a command line REPL environment like you get in ipython/matlab/R/mathematica. That may be even not be so difficult to implement, as expressions can already be computed on the fly. Basically, the input field in the run dialog already provides most of the functionality.

Something like this:

Welcome to the Kerbulator command line...

> current_sma = ((Craft.Ap + Parent.R) + (Craft.Pe + Parent.R)) / 2
current_sma = 573948.2839283

> speed_at_Pe = orbital_velocity(current_sma, Craft.Pe + Parent.R, Parent.mu)
speed_at_Pe = 2134.394032

> desired_sma = ((400E3 + Parent.R) + (Craft.Pe + Parent.R)) / 2
desired_sma = 693948.2839283

> desired_speed = orbital_velocity(desired_sma, Craft.Pe + Parent.R, Parent.mu)
desired_speed = 2432.394032

> delta_v = desired_speed - speed_at_Pe
delta_v = 202

# Some functions like 'make_node', 'set_alarm' could be defined by Kerbulator
> make_node(delta_v, 0, 0, Craft.TimeToPe)
Node set.

 

I really wish I had more knowledge about how to made a good editor widget in Unity. The function editor is a mess currently (stupid font, arrow keys don't work, scrolling also zooms the ship, etc.).

Edited by wmvanvliet
Link to comment
Share on other sites

12 minutes ago, wmvanvliet said:

Hrm, but that would mean that Kerbulator spams your screen with windows you have to manually close every time you run a function. Handy for the use case you describe above, but a pain in other cases.

Also, what would happen when you need the output of a function twice? For example, you need the speed at Ap and at Pe and you want to use the visviva function to compute both.

This is true. There is a fine line between adding a nice feature and annoying users. A workaround would be the following:
Add a button to the function windows to "stick" the window to the screen. If a window sticks to the screen it will not close when
you open another window, even if the new window contains the same function. This gives these use cases:

Option1: Chain two functions:
Open the first window with the first formula. Enter your values and click on the "stick" button. Now the window gets a unique title
"window1" or "func1" for example. You can now move around this window and open the second one. The first window stays open
and can now be referenced by its title, e.g. "func1.Ap" or "func1.velocity".

Option2: Use the same function twice:
There is no distinction between functions so you could open the same function twice. The first has to be sticked first but the second
just functions normally (could be sticked too but does not need to). If you stick another one the new one gets an unique name as well,
"func2" for example, Now you can grab func1.Pe and func2.Ap without ambiguity.

Option3: Normal use without chaining:
Just dont use the stick button. There will still be only one window and you do not have to close them.

So in essence you have two kinds of windows. Sticky ones and nonsticky ones. The sticky ones just stay open and will get unique names.
To close them you have to close them manually. The nonsticky ones work like they do now, so you can only have one of them, a newer
one will close the old one.

23 minutes ago, wmvanvliet said:

Really what you want is a command line REPL environment like you get in ipython/matlab/R/mathematica.

From a functionality perspective, yes. However, a scrolling log where you have to type everything is not too different from just
writing a function, only that you do it piece by piece. You can combine this with a GUI to get the best of both worlds. By using
windows you can arrange them on the screen as you like. Some intermediate values like periapsis can be kept visible and
updated in real time (by using your auto-run-feature). And if you want to redo a calculation you dont have to press up in your
history until you get the equation, rerun it, and repeat this for each equation. Having used Matlab its sometimes annoying to
rerun a chain of >7 functions each time you do a change.

If you use seperate windows however, all you need to do is click a few buttons in the right order, and you also have a visual
indication which value needs to be updated. Even more comfortable, if you set each chained function to auto-rerun, the whole
chain updates in realtime. This is something you do not get with a command line.

30 minutes ago, wmvanvliet said:

The function editor is a mess currently (stupid font, arrow keys don't work, scrolling also zooms the ship, etc.).

I had no issues with the font, and scrolling zooms the ship is an issue every mod i used had, so no worries here. If you add
another button (and you already have buttons, so that would be a minor rework) you would not have to deal with the editor widget
mess of unity.

Link to comment
Share on other sites

45 minutes ago, Gotbread said:

However, a scrolling log where you have to type everything is not too different from just
writing a function

It adds a lot more. For one, it is a place for the "global" variables to live. You can give names to the output of functions so they don't clash. Plus, you can make small tweaks when you re-use a variable:

> v = orbital_speed(...)
v: ...

> t = some_computation(v * 2)
t: ...

This is flexibility you won't get with a GUI.

48 minutes ago, Gotbread said:

By using
windows you can arrange them on the screen as you like. Some intermediate values like periapsis can be kept visible and
updated in real time (by using your auto-run-feature). And if you want to redo a calculation you dont have to press up in your
history until you get the equation, rerun it, and repeat this for each equation. Having used Matlab its sometimes annoying to
rerun a chain of >7 functions each time you do a change.

If you use seperate windows however, all you need to do is click a few buttons in the right order, and you also have a visual
indication which value needs to be updated. Even more comfortable, if you set each chained function to auto-rerun, the whole
chain updates in realtime. This is something you do not get with a command line.

True. If I'm going to add a feature, I prefer to do it right and thoroughly. So lets explore this GUI scenario.

Here is a mockup of how it could work:

3AqWWc5.png

The user can "pin" a function to the interface by clicking the push-pin button next to the "close window" button. Pinning a window will remove the "inputs" clutter from the window and keep it open. The name of the function is the title of the window. This is similar to the "auto-run" window. Hovering the mouse on the pinned window will display a tooltip: "Click to edit". Clicking on the pinned window will open the full interface again, so you can edit the inputs and have access to running it again and other functions.

When the user pins the same function twice, the second window title will be the function name + "2" ("3", "4", etc.).

The output variables of a pinned or auto-running function can be used as input for other functions, by the name of WindowTitle.VariableName. Kerbulator internally keeps a graph of which functions are used as input to other functions (no cycles allowed). A line between the function windows is drawn in the interface to visualize this. When the user re-runs a function, all dependent functions will be re-run as well. This is also true when auto-running a function: all dependent function will also enter auto-run mode.

It's going to take some work to get this right :)

Link to comment
Share on other sites

  • 5 weeks later...

Just stumbled into this mod thanks to Kerbal Engineer not working on 1.2 Pre. I am in dire need to find a way to calculate my orbital period.

Trying to get Orbital Period outputted  n minutes using this

in: Pe "Periapsis"
in: Ap "Apoapsis"
out: T  "Orbital Period"



M = Parent.M
R = Parent.R
r_min = R + Pe
r_max = R + Ap
μ = M*G
a = (r_min + r_max) / 2

T = (2 * π * √ (a∧3) / μ) / 60

But I am not getting an output that seems even remotely right. Any help would be much appreciated!

 

Ps. This is now going to be one of my go to mods (may even replace KER), I am loving it so far.

Link to comment
Share on other sites

You got the wrong math symbol. The ∧ symbol means the logical 'and' operation, while the ^ symbol means taking the power. The ∧ symbol is a recent addition to Kerbulator. It hadn't occurred to me yet how similar it is to ^.

The last line should read:

T = (2 * π * √ (a^3) / μ) / 60

Note that your formula will give you the orbital period in minutes (you divide by 60).

Edited by wmvanvliet
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...