Darwinbots Forum
Code center => Darwinbots3 => Topic started by: Numsgil on February 25, 2011, 09:11:24 PM
-
I'm playing with the idea for bots to have a memory array of booleans in addition to the one for integers.
I suspect most people wouldn't care either way, but I have two different ideas for how this would work in DNA; if anyone has any compelling ideas for which one to choose, etc. I'd like to talk this through.
Idea 1:
If 'store' is storing to a negative location, it pops a value from the boolean stack instead of the integer stack and stores it in boolean memory.
Example:
true -10 store would store 'true' to the 10th element of the boolean memory array.
Pros: No additional commands
Cons: The behavior of store, as far as whether it pops the boolean stack or integer stack, is not immediately evident in all cases, since you have to figure out the sign of the top value of the integer stack when the store command is called.
Idea 2:
A separate command stores to the boolean stack. Maybe:
true 10 flag (here, flag is being treated as a verb with it's definition which means "to signal")
Pros: It's easier to link up boolean sysvars that might control a specific integer's behavior, since they can share the same address. It's a stupid example, but if there were a "Launch X ICBMs" sysvar, you could have the corresponding number in the boolean array control whether the command should be obeyed or not. Eg: true .icbmlaunch flag 10 .icbmlaunch store. I can't think of any real sysvars we'd want to do this for, but an idea anyway.
Also, we can add extra commands that don't necessarily make sense for the integer array. Things like "toggle", which would turn that memory location to its reverse. Likewise, right now the DNA module doesn't have inc, but it we added it, it only makes sense for an integer array.
Cons: More commands (whether that's bad or not depends on your perspective, though, I suppose).
...
Anyway, the main reason I'm thinking about this is that we could add a "waituntil" command to the DNA that would cause the executing chromosome to abort execution of the DNA until a certain boolean memory location were true. Then, when the boolean memory location is true again, it can resume from that location in teh DNA. Makes it possible to build DNA scripts meant to run over several cycles, like a high level instruction set for building a multibot.
Also, some sysvars are inherently boolean in nature and it's not always easy to think of a continuous version that makes numbers from [-9999, 9999] meaningful. Vision, for instance. .isBot is just more intuitive than some sort of coded type system (1 = bot, 2 = shape, etc.)
-
Hmm. How would maths work with this? Say you want to go forward if X (bool) is true in a conditionless bot, what would you do? Would 40 .up *.X mult store work? When trying to multiply by true, is it treated at one?
-
booleans are on a separate stack from integers, and mult only works with integers.
'store' still either works or not based on the top value of the (boolean) stack. That would be true regardless of which of the two ideas we end up using.
-
Okay, I'm confused.
-
Ah actually, when I work through it, my first idea wouldn't work anyway, because the top value of the bool stack has to be true or the store command won't work anyway. So you could only ever store 'true' values to boolean memory. I'll need to work through the second idea and see if I can make it work, then.
-
I will go with this if we can intergrade it better with condition structure, otherwise we get the same annoyance you guys Xed me from implementing earlier:
Remember when I was going to tweak Pandas code to use vegetable or chloroplast settings, and you guys said it will be confusing for the end user to have both?
similar situation here...
-
How about:
1.) Let's say we got 20 genes
2.) In the code we got -40 store
This means on the next cycle:
The 40 mod 20 gene's activation is reversed.
I am only suggesting this because, in my evo sim , there is less then 1% use of the condition part of the gene.
-
The new DNA doesn't really understand what a "gene" is. It's just a stream of byte code.
-
wha? :blink: details plz??
-
Take a look at the thread about DNA. There's an interpreter there to play with.
There just isn't anything analogous to a gene. It's just a list of instructions that get followed in a more or less linear fashion. Maybe codules could be seen as a analog to a gene. But the comparison is sorta weak.
-
I've implemented the in-place condition programming I talked about in another thread. stores and codule calls (not implemented yet, but it will be) will still pull values from the stack, but nothing will happen if the top value on the bool stack is false. An empty bool stack is treated as true.
Can you give an example?
-
false
10 20 store
*20
Try that in the interpreter. You should get back 0 on the stack. Meaning that the store to memloc 20 didn't happen.
Compare with this code:
true
10 20 store
*20
-
oh, ok (I still can not find the thread with your interpreter though, I hope it is an exe...)
-
Try this thread (http://forum.darwinbots.com/index.php/topic,2207.0.html)
It was stickied at the top of the forum.
-
somewhat related:
Can we add inttobool and booltoint?
inttobool takes (duplicate into memory) a number on the integer stack converts it to a bool ( int > 0) and does a push into the bool stack
booltoint takes (duplicate into memory) a boolean on the bool stack converts it to an integer (0 or 1) and does a push into the integer stack
-
I'm not necessarily against it, but when would that be useful? I can't think of any use cases where you'd need to do that except for storing true/false flags to memory, and then you could do something like:
1 custommemoryloc store not 0 custommemoryloc store
-
I was hoping you'll ask:
I recently did an AI project for school myself. It has no real Boolean logic, example:
IF True THEN Sin 29 * CALC Memory(121) OUT Do_Nothing TYPE action DIRECTION clone_up
IF True THEN 250 7 216 * CALC Memory(170) OUT Do_Nothing TYPE action DIRECTION clone_down
IF True THEN Sin 29 * CALC Memory(121) OUT Do_Nothing TYPE action DIRECTION clone_up
IF True THEN Sin 29 * CALC Memory(121) OUT Do_Nothing TYPE action DIRECTION clone_up
IF Memory(167) < Memory(36) THEN 142 0 CALC Memory(99) OUT Do_Nothing TYPE data DIRECTION clone_up
IF True THEN 29 * CALC Memory(197) OUT Do_Nothing TYPE action DIRECTION clone_up
IF Memory(234) = Memory(211) THEN 206 * CALC Memory(178) OUT Do_Nothing TYPE action DIRECTION clone_up
IF True THEN 351.508334281997 1 Cos 39.1118722540835 Cos CALC Memory(76) OUT Do_Nothing TYPE data DIRECTION clone_up
IF False THEN 202 * 217 * CALC Memory(7) OUT Gear2_Reverse TYPE data DIRECTION clone_up
IF True THEN Distance 161 0 * * Sin * 241 * CALC Memory(174) OUT Do_Nothing TYPE data DIRECTION clone_up
IF False THEN 34.3416983468838 202 * 217 * CALC Memory(7) OUT Gear2_Reverse TYPE data DIRECTION clone_up
IF Memory(133) != Memory(213) THEN * 61 * CALC Memory(110) OUT Do_Nothing TYPE data DIRECTION clone_up
After CALC is the destination of the data (math) result
One of the operators I have is called "Angle_Compare" (btw: I am considering this for DB as well) It compares two angles using this algorithm:
hold1 = popstack(a) '100
hold2 = popstack(a) '99
calc = IIf(angle_compare(hold1, hold2), 2, -2)
If MD_state = 5 And a = cntrl_math Then debug_print.Text = debug_print.Text & vbNewLine & hold1 'debug
If MD_state = 5 And a = cntrl_math Then debug_print.Text = debug_print.Text & vbNewLine & hold2 'debug
If MD_state = 5 And a = cntrl_math Then debug_print.Text = debug_print.Text & vbNewLine & "DIR:" & calc 'debug
pushstack(a, calc)
Private Function angle_compare(ByVal ang1 As Single, ByVal ang2 As Single) As Boolean
Dim data2 As Integer = ang2
Dim data1 As Integer = ang1
Dim out As Boolean
Dim sp As Boolean = False
If data1 > 180 Then
sp = True
data2 = 360 - data2
data1 = 360 - data1
End If
If (data2 > data1) And (data2 < (data1 + 180)) Then out = True Else out = False
If sp Then angle_compare = IIf(out, True, False) Else angle_compare = IIf(out, False, True)
End Function
As you can see since there is no real Boolean stack; The functions result is always stored as Integer (2 , -2) and then can be stored into a memory location. Then the system can always compare the result > v. zero. This kind of model worked pretty good for me.
The button line is it will add flexibility of using a Boolean operator as a data operator and vise-versa.
Think about "angle_compare": In DB it will take two Integers and return an Integer (2 or -2) , but it will be cool to turn it into a Boolean right away.
You may catch me here on the fact that I am making an imaginary concept (intotobool) on concept that's imaginary as well (angle_compare) but I hope it'll be alright.
-
lol, Numsgil did that post actually made sense since you are slow to reply? :D
-
Sorry, I got distracted trying to figure out what your angle_compare was trying to do.
I think it's probably something you can do using a dot product or 2D cross product. Usually when you have to break something out in terms of angles it's a sign you're doing it wrong (at least in terms of programming).
That is:
A dot B = |A| * |B| * cos(angle between them)
So:
(A dot B ) / (|A| * |B|) = cos(angle between them)
And for the 2D cross product:
(A cross B ) \ (|A| * |B|) = sin(angle between them)
Using those two identities you can often get rid of all the trig, which is better computationally and more elegant from a computation standpoint.
-
Ouch, that math looks heavy...
I am guessing (angle between them) is: ang1 - ang2
Right?
I also have to assume that A and B are vectors relative to zero
Right?
What values does that formula return?
-
Yeah, angle between them is the difference in their relative angles.
And yes, it only really makes sense if A and B are directional vectors and not points.
The dot product is just:
A.x * B.x + A.y * B.y
Cross product is:
+/- (A.x * B.y - A.y * B.x)
(+/- depending on what "handedness" you're using).
-
I remember learning this at Delft university. This has confronted me with the knowledge that I can no longer reproduce this on my own. Knowledge has a half life...
-
Wow, this formula is awesome. Thx for teaching me that Numsgil. , I did some basic tests on it, I will do rigorous testing on it when I get a chance.
-
I just realized I don't need to divide by (|A| * |B|) because all it does is rescale the triangle.
-
if A and B are unit length, you don't need to. Or if they cancel out in some way later in the problem, you don't need to.