# This post is for an outdated version of Funky Trees. Comparison operators have been added!

Feel free to check out the (now more relevant) post by snowflake.

**Nice Clickbait. A long read, but might be worth it. Scroll down if you just want to see the flight system.**

Here’s some potentially useful info to help you make some smart machines with the funky trees update. I also included a nice system that I have been working on at the end. As a quick disclaimer – I am only a novice at coding, so please be gentle with me!

# How to Compare Values With Funky Trees

With the development of funky trees, many people, including me, asked if it was possible to use comparison operators (*>, < , <= , >=, ==*) with the new input system. At this time, the answer is **no**.

**So, is it not possible to compare values in the current state of funky trees?**

Of course, those nifty inequality symbols help a TON with comparative logic, but the same effect can be produced without them. The concept behind this is called “selection by calculation” - a somewhat disgusting topic that I had to suffer through as part of a coding course that I took about a year ago. In “selection by calculation”, arithmetic can be combined with functions such as `ceil`

, `floor`

, `clamp`

, and `clamp01`

, to produce a value of `1`

or `0`

when a certain variable reaches a desired value. Functionally, this is similar, if not identical to, those fancy operators that are not in funky trees (*>, <, <=, >=, ==*). At least in the few coding languages that I am familiar with, comparison produces a value of `1`

or `0`

, which translates to `true`

or `false`

in code-speak. For example, the following expressions, which are `true`

, would be evaluated to `1`

:

`5 > 1`

`25 == 25`

So, the behavior of comparison can be replicated by using some math, but what does it look like? The answer to that isn’t too simple, but it can be answered by another question. For example, I ask myself, “how can I make this expression equal `zero`

when it is `false`

?”, or “how can I make this expression equal `one`

when it is `true`

?”. Division, subtraction, and multiplication are excellent tools to reduce an expression to `1`

or `0`

. The functions, `ceil`

, `floor`

, `clamp`

, `clamp01`

, and even `sign`

, are also extremely valuable to use. The goal, then, is to use some math to produce a `0`

when the intended comparison is `false`

, and a `1`

when the comparison is `true`

. When crafting a comparative expression, try using some test values to see if it works.

While I can ramble on about weird arithmetic, it would probably be more useful to show some examples. Here are some expressions, and their comparative twins, for you to look at:

`clamp01(X - 5)`

is the same as *X > 5*

For test values -2, 1, 5, and 7, each equation values as…

X = `-2`

------> `0`

is the same as *0*

X = `1`

-------> `0`

is the same as *0*

X = `5`

-------> `0`

is the same as *0*

X = `7`

-------> `1`

is the same as *1*

`clamp01(5 – X)`

is the same as *X < 5*

For test values -2, 1, 5, and 7, each equation values as…

X = `-2`

------> `1`

is the same as *1*

X = `1`

-------> `1`

is the same as *1*

X = `5`

-------> `0`

is the same as *0*

X = `7`

-------> `0`

is the same as *0*

Note that I didn’t include an equivalent expression for the `equal to`

operator (`==`

). Note that such logic can be done, but isn’t too useful. An exact value rarely happens in SP, so it is better to use tolerancing.

Tolerancing can be done with the functional equivalent to the `and`

(*&&*) operator. This is very simple to do, and can be done by **multiplying two comparative functions to each other**. For example, lets use the two functions that were previously developed:

`clamp01(X - 5) * clamp01(5 – X)`

Note that no value for X can be used to make this function evaluate to `1`

, or `true`

.

This “selection by calculation” can be applied to SP to make some nice automated systems. Take for example, an altitude indicator that tells the pilot when their altitude is too low (maybe below 750 feet). This would probably be made of a beacon light that turns on when *Altitude < 750*. The previously discussed syntax can be used here:

`clamp01(750 – Altitude)`

Let’s verify with some test values.

Altitude = `-100`

------> Evaluates to `1`

Altitude = `500`

-------> Evaluates to `1`

Altitude = `750`

-------> Evaluates to `0`

Altitude = `1000`

------> Evaluates to `0`

This means that the light will turn on at altitude values of `500`

and `-100`

. An input value of `1`

means that the light turns on.

# Showing Off My Spaghetti Code

“Selection by calculation” is very useful for making all sorts of stuff, but my first (successful) use of it was in a VTOL flight system capable of **maintaining a steady altitude, descending at a constant speed, and ascending at a constant speed**. This means easy hovering, and easy landing! A lot of comparative logic is used here to have an upward-facing VTOL nozzle fire (or stop firing) when a desired vertical velocity (negative, zero, or positive) is reached. The VTOL power is also regulated by throttle, and a unique comparison (case) is used for VTOL up, center, and down. Specifically, each case is a “block” of code, and each “block” is added in the overall code. Here’s a graphic of a top-level view of the code:

Each case is isolated by the use of addition, and is evaluated to be zero when it is not valid. For example, if the VTOL bar is set at its center, term 2 and 3 evaluate to be zero. Each case contains, then, a VTOL comparison term, throttle term, and unique descent/ascent/hover term, all multiplied (`and`

logic). Here’s a… less top-level version of that graphic.

Note that the code could **definitely** be streamlined. Additionally, a smoothing term was added to the “hovering” term (1) to make the ride a little less bumpy. The ascent/descent terms are compared to a vertical velocity that is determined by a max value, combined with the position of the VTOL slider. Vertical velocity can also be reflected by `GS * sin(AngleOfAttack + PitchAngle)`

. Here’s the final code, and a graphic to represent it, respectively:

`clamp01(1 + sign(VTOL)) * clamp01(abs(GS) * abs(sin(AngleOfAttack + PitchAngle)) + 0.15) `

* (Throttle * -1 * sign(AngleOfAttack + PitchAngle)) * (1 - clamp01(ceil(VTOL))) +

clamp01(-1 * sign(VTOL)) * clamp01(1 - (sign(AngleOfAttack + PitchAngle))) *

clamp01(GS * abs(sin(AngleOfAttack + PitchAngle)) - 25 * abs(VTOL)) * Throttle +

clamp01(ceil(VTOL)) * Throttle * -1 *

clamp(GS * sin(AngleOfAttack + PitchAngle) - 25 * abs(VTOL), -1, 0)

*The flight module itself can be downloaded here! Feel free to give it a spin.*

**Well, thanks for reading! Hope that the tutorial makes sense. Feel free to ask questions – I’ll try my best to answer them.**

@spefyjerbf THANK YOU!!

@JuanShot2Go Snowflake made a pretty good post. This post should have everything you need to know about booleans, comparison operators, and logical operators.

@JuanShot2Go

Really!! Is there documentation?

I saw the update https://www.simpleplanes.com/Forums/View/1042680/Funky-Trees

But no mention of it there.

@JuanShot2Go Ty! This post relates to an outdated version of funky trees, though. Now we have booleans, which is really useful.

Nice work.

@spefyjerbf thanks! Now to reverse engineer it, so i can be a funk trees ameteur instead of not knowing it at all

@robloxweponco something along the lines of

clamp01(500 * Throttle - GS * cos(AngleOfAttack))should work. You may need to make the entire expression negative.Im trying to make a variable inverted airbrake with a set max speed, if the max speed is 500, and if i set throttle to 50%, i would get a speed of 250. Ive tried many methods but none seem to work, any ideas?

@SnoWFLakE0s Yep! That should work.

I wonder if it would work if I did something like:

a-0.01 < x < a+0.01, but with * to have multiple qualifiers.

So something like this:

`clamp01(ceil(X - 1.99)) * clamp01(ceil(2.01 - X))`

In theory, this should mean that if X is both larger than 1.99 and smaller than 2.01, the function will evaluate to 1, thus letting for a pretty precise qualifier for a value of a = 2.

@SnoWFLakE0s Perhaps apply a clamp01 (and maybe even a floor) to your expression.

Perhaps the expression would be something along the lines of floor(clamp01(x / a)) might work.

Otherwise I would tolerance it or use some spaghetti sign logic.

@spefyjerbf

.

Hey spefy, I've come upon a pretty large need for the ability to make an equation operator. Mind showing me how this might be done? I was thinking to divide x by a in order to check if x/a = 1, but this fails if x is larger than a. Any hints here?

@XjayIndustrys Thank you! It was fun and useful to write this forum post.

Also really cool! I like all the red stuff and the time put into making this!

I only read the memes @WNP78 what would happen?

@spefyjerbf Video Example of what it looks like

@BuiltBionixInd10 I'm sure that an autopilot would be possible for a walking mechanism. As for how to do it, that goes over my head. I have never been too good with mechs.

meanwhile here I am trying to figure out if I can translate this to a Blade T2000

@BuiltBionixInd10 Video Example

@spefyjerbf could be this possible like piloting a mech

When there is no pilot it will autopilot or AI mode

I didn't know if you tried that advantage of funky trees

Ah yes, the transition from analog to digital, gonna try it out!

I knew this would happen xD

@spefyjerbf

.

Much thanks for the kind words, added to my contacts. Will contact ya when I need help.

@SnoWFLakE0s Constantly improving has been one of the most rewarding parts of everything that I do on the site. Feeling that something unpolished is a natural part of that process. If you want constructive criticism, though, feel free to contact me via this website or on discord. My discord is spefyjerbf#8985.

@spefyjerbf

.

Thanks, I often feel my stuff is slightly unpolished- been taking some inspiration from you as well!