Darwinbots Forum
Code center => Bugs and fixes => Solved Bugs => Topic started by: Griz on October 27, 2005, 08:12:04 PM
-
ok.
attn Nums!!!!!!!!!
I reported this before.
I keep getting this same runtime error 6 overflow.
in the Senses modual ... lookoccurr routine.
rob(o).vx is out of range.
now ...
you said the following would fix this ...
but you didn't specify if all of this had to be changed or where to insert it.
~~~
if abs(rob(o).vx) > rob(o).MaxVel then rob(o).vx = sgn(rob(o).vx) * rob(o).MaxVel
if abs(rob(o).vy) > rob(o).MaxVel then rob(o).vy = sgn(rob(o).vy) * rob(o).MaxVel
rob(n).mem(refvelup) = (rob(o).vx * Cos(rob(n).aim) + rob(o).vy * Sin(rob(n).aim) * -1) - rob(n).mem(velup)
rob(n).mem(refveldn) = rob(n).mem(refvelup) * -1
rob(n).mem(refveldx) = (rob(o).vy * Cos(rob(n).aim) + rob(o).vx * Sin(rob(n).aim)) - rob(n).mem(veldx)
rob(n).mem(refvelsx) = rob(n).mem(refvelsx) * -1
~~~
please, please, please, please ...
would you tell me exactly where in the following rountine this code goes ...
because if I put this at the top of the routine ...
I get a compile error ...
"method or data member not found."
and this highlighted:
Public Sub lookoccurr(n As Integer, o As Integer)
you guys want us to be specific when reporting the bugs ....
would you please be as specific with the fixes? ;)
and/or ...
might someone who now has a stable 2.37.4 upload it as 2.37.4b or something.
I sure would like to be running it as well.
thank you
~griz~
~~~~~~~~~~~~~~~~
' copies the occurr array of a viewed robot
' in the ref* vars of the viewing one
Public Sub lookoccurr(n As Integer, o As Integer)
If rob(n).Corpse Then Exit Sub
Dim t As Byte
'If rob(n).lastviewed <> rob(o).AbsNum Then
For t = 1 To 8
rob(n).mem(occurrstart + t) = rob(o).occurr(t)
Next t
rob(n).lastviewed = rob(o).AbsNum
'End If
If rob(o).nrg < 32001 Then
rob(n).mem(occurrstart + 9) = rob(o).nrg
Else
rob(n).mem(occurrstart + 9) = 32000
End If
rob(n).mem(occurrstart + 10) = rob(o).age '.refage
rob(n).mem(in1) = rob(o).mem(out1)
rob(n).mem(in2) = rob(o).mem(out2)
rob(n).mem(711) = rob(o).mem(18) 'refaim
rob(n).mem(712) = rob(o).occurr(9) 'reftie
rob(n).mem(refshell) = rob(o).Shell
rob(n).mem(refbody) = rob(o).body
rob(n).mem(refypos) = rob(o).mem(217)
rob(n).mem(refxpos) = rob(o).mem(219)
if abs(rob(o).vx) > rob(o).MaxVel then rob(o).vx = sgn(rob(o).vx) * rob(o).MaxVel
if abs(rob(o).vy) > rob(o).MaxVel then rob(o).vy = sgn(rob(o).vy) * rob(o).MaxVel
'give reference variables from the bots frame of reference
rob(n).mem(refvelup) = (rob(o).vx * Cos(rob(n).aim) + rob(o).vy * Sin(rob(n).aim) * -1) - rob(n).mem(velup)
rob(n).mem(refveldn) = rob(n).mem(refvelup) * -1
rob(n).mem(refveldx) = (rob(o).vy * Cos(rob(n).aim) + rob(o).vx * Sin(rob(n).aim)) - rob(n).mem(veldx)
rob(n).mem(refvelsx) = rob(n).mem(refvelsx) * -1
rob(n).mem(refvelscalar) = CInt((CLng(rob(n).mem(refvelup)) ^ 2 + CLng(rob(n).mem(refveldx)) ^ 2) ^ 0.5)
'replaced following line. overflow
'rob(n).mem(refvelscalar) = Sqr(rob(n).mem(refvelup) ^ 2 + rob(n).mem(refveldx) ^ 2) ' how fast is this robot
moving compared to me?
rob(n).mem(713) = rob(o).mem(827) 'refpoison. current value of poison. not poison commands
rob(n).mem(714) = rob(o).mem(825) 'refvenom (as with poison)
rob(n).mem(715) = rob(o).kills 'refkills
If rob(o).Multibot = True Then
rob(n).mem(refmulti) = 1
Else
rob(n).mem(refmulti) = 0
End If
If rob(n).mem(474) > 0 And rob(n).mem(474) <= 1000 Then 'readmem and memloc couple used to read a
specified memory location of the target robot
rob(n).mem(473) = rob(o).mem(rob(n).mem(474))
'rob(n).mem(474) = 0
End If
If rob(o).Fixed Then 'reffixed. Tells if a viewed robot is fixed by .fixpos.
rob(n).mem(477) = 1
Else
rob(n).mem(477) = 0
End If
rob(n).mem(825) = rob(n).venom
rob(n).mem(827) = rob(n).poison
End Sub
There, fix should be self evident (unless you're color blind ;))
-
I've posted changes in your post in red.
-
Griz says it's still crashign so whoever actually attempts to fix this bug in an official version double check over everything. The idea should be basically sound...
-
OK then, so the fix doesn't work. It's back in reports so people can say what happened, if there was any change using the fix, etc. ^_^
OK?
-
OK, this is my task for the day. To figure out what is wrong with this routine.
Has anyone else ever seen this error? and if so, how do I reproduce it because I can't get it to break. :(
-
Are we saying that rob(o).vx is a whole lot bigger than it should be?
I'm not seeing it
-
Probably since you're subtracting velup at the end, and velocity was insanely huge prior, that's where the problem is.
abs(velup) should be less than MaxVel I think.
-
It certainly should.
In fact since the addition of the maxvel variable I don't think I have ever seen an insanely large velocity. That's why I put Maxvel in, to stop this kind of stuff dead. Thought it had! :(
-
You could check all the routines that modify velocity to see if they're bounds checked against MaxVel.
-
There is something weird going on here. :blink:
In this code there is no such thing as .MaxVel
It simply does not exist as a data member of rob() so your lines of code would actually cause a crash.
I added MaxVel as a data member of rob() ages ago so where the F%$# has it gone? :blink:
-
I just remembered what happened.
.MaxVel never existed.
maxvel was added as a sysvar and is based on a local variable called "Maxspeed" that is calculated in subroutine "updpos" in the Physics module.
The formula for Maxspeed is
Maxspeed = 30 / (.mass / 2)
Since robots are supposed to have a minimum mass of 1, this results in a ceiling value of 60
I have extensively tested the actual speed limit code (also found in the same subroutine) by manually entering all kinds of weird and huge numbers into .vx and/or .vy and can safely say there is nothing wrong with this part of the code.
vt = Sqr(.vx ^ 2 + .vy ^ 2)
If vt > Maxspeed Then 'top speed limit routine 2 changed faster speeds for lower mass robots
Reduce = vt / Maxspeed
.vx = .vx / Reduce
.vy = .vy / Reduce
End If
So the only thing left is that somehow the mass of the robot is getting too small so that Maxspeed is coming back huge.
So I'm off to test that now.
-
Next update.
Robot mass is defined in routine "updvars2" in the "Robots" module
.mass = 1 + (.body / 10000) + (.Shell / 200) 'set value for mass
Maxspeed = 30 / (.mass / 2) 'Set maximum speed. Absolute max = 60
You will note that the same Maxspeed calculation is in here too. This one is applied to limit acceleration vectors prior to passing the program flow to the afore mentioned "updpos" routine
As you will see from this formula, the only way to make Maxspeed bigger than 60 is to have a mass of less than 1.
this can be achieved in two ways
One way is to have a body size that is large and negative, A body of -10000 would yield infinite Maxvel and would crash the program right here.
Another is for shell to be negative and close to 200 in size.
I have manually put all kinds of values in here and none cause the crashes reported since even a maxspeed value of 32000 doesn't crash anywhere
Since the reported crashes only occur when one robot sees another with a huge velocity, this isn't really surprising. It could go un-noticed for a few cycles before it becomes an issue.
However, a negative body could not go un-noticed as the bot will die on the following cycle.
Negative shell? Now that is a different matter. It won't have any direct effect on the bots life other than dramatically reducing its mass.
The plot thickens and the delving into the code continues. More in a bit.
-
Unable to find any way to make .shell or .body negative. Every test was caught by the automatic limits already in place in the software and set back to a valid value.
The only remote possibility is if the offending robot is a corpse which would allow it to have a negative body (maybe)
I have modified the code in "updvars2" in the robots module as follows
Before
With rob(n)
.mass = 1 + (.body / 10000) + (.Shell / 200) 'set value for mass
Maxspeed = 30 / (.mass / 2) 'Set maximum speed. Absolute max = 60
Absaccel = 0 'reset acceleration
If Abs(.vx) > 32000 Then .vx = 32000 * Sgn(.vx)
If Abs(.vy) > 32000 Then .vy = 32000 * Sgn(.vy)
.absvel = Cos(.aim) * .vx * -1 + Sin(.aim) * .vy 'formula changed to give velocity in the direction robot is facing rather than always a positive number. Make *.vel work properly.
after
With rob(n)
If .Shell < 0 Then .Shell = 0
If .body < 0 Then .body = 0: .Dead = True
.mass = 1 + (.body / 10000) + (.Shell / 200) 'set value for mass
Maxspeed = 30 / (.mass / 2) 'Set maximum speed. Absolute max = 60
Absaccel = 0 'reset acceleration
If Abs(.vx) > 32000 Then .vx = 32000 * Sgn(.vx)
If Abs(.vy) > 32000 Then .vy = 32000 * Sgn(.vy)
.absvel = Cos(.aim) * .vx * -1 + Sin(.aim) * .vy 'formula changed to give velocity in the direction robot is facing rather than always a positive number. Make *.vel work properly.
This should prevent any possible huge value of Maxspeed ever occuring.
Without huge Maxspeed, you can't have huge speed so the refvel stuff where the error was actually spotted, should be fixed.
I won't move this to the fixed thread yet until the repair is confirmed.
-
Could someone please confirm that Corpses were enabled in sims that produced this fault?
-
I allways have corpses turned on so it could very well be. But I'm getting a little confused here now. You're talking about more than one solution here for the same overflow error, is that right? I've lost track what to change first. see my post 'Still get overflows' where you mension another solution.
-
Not more than one fix.
Num's idea in the other thread is a work-around. It addresses the symptom without finding the root cause.
This fix here will stop the robots moving too fast in the first place so the other issue will never even arise.
-
So... These are not needed anymore?
if abs(rob(o).vx) > rob(o).MaxVel then rob(o).vx = sgn(rob(o).vx) * rob(o).MaxVel
if abs(rob(o).vy) > rob(o).MaxVel then rob(o).vy = sgn(rob(o).vy) * rob(o).MaxVel
I'll only change the robot code you mensioned here, is that it?
But the code that was there before I put the .maxwell codes in are gone, so I doubt it will work just like that. I think I need to download the sourcecode again and just add the latest solutions you've mensioned here. ..I guess. O, my...
-
In 2.4 I believe I changed MaxVel to either a SimOpts member or a robot member and set it equal to 60 for all bots (since heavier bots now cost more to move... didn't seem right to limit their max velocity if they can output the energy to get there).
-
Not only are these lines not needed. They are impossible
rob(o).MaxVel does not exist and will cause a crash as soon as you try to execute it.
Here is the original, unaltered code for the entire lookoccur routine.
' copies the occurr array of a viewed robot
' in the ref* vars of the viewing one
Public Sub lookoccurr(n As Integer, o As Integer)
If rob(n).Corpse Then Exit Sub
Dim t As Byte
'If rob(n).lastviewed <> rob(o).AbsNum Then
For t = 1 To 8
rob(n).mem(occurrstart + t) = rob(o).occurr(t)
Next t
rob(n).lastviewed = rob(o).AbsNum
'End If
If rob(o).nrg < 32001 Then
rob(n).mem(occurrstart + 9) = rob(o).nrg
Else
rob(n).mem(occurrstart + 9) = 32000
End If
rob(n).mem(occurrstart + 10) = rob(o).age '.refage
rob(n).mem(in1) = rob(o).mem(out1)
rob(n).mem(in2) = rob(o).mem(out2)
rob(n).mem(711) = rob(o).mem(18) 'refaim
rob(n).mem(712) = rob(o).occurr(9) 'reftie
rob(n).mem(refshell) = rob(o).Shell
rob(n).mem(refbody) = rob(o).body
rob(n).mem(refypos) = rob(o).mem(217)
rob(n).mem(refxpos) = rob(o).mem(219)
'give reference variables from the bots frame of reference
rob(n).mem(refvelup) = (rob(o).vx * Cos(rob(n).aim) + rob(o).vy * Sin(rob(n).aim) * -1) - rob(n).mem(velup)
rob(n).mem(refveldn) = rob(n).mem(refvelup) * -1
rob(n).mem(refveldx) = (rob(o).vy * Cos(rob(n).aim) + rob(o).vx * Sin(rob(n).aim)) - rob(n).mem(veldx)
rob(n).mem(refvelsx) = rob(n).mem(refvelsx) * -1
rob(n).mem(refvelscalar) = Sqr(rob(n).mem(refvelup) ^ 2 + rob(n).mem(refveldx) ^ 2) ' how fast is this robot moving compared to me?
rob(n).mem(713) = rob(o).mem(827) 'refpoison. current value of poison. not poison commands
rob(n).mem(714) = rob(o).mem(825) 'refvenom (as with poison)
rob(n).mem(715) = rob(o).kills 'refkills
If rob(o).Multibot = True Then
rob(n).mem(refmulti) = 1
Else
rob(n).mem(refmulti) = 0
End If
If rob(n).mem(474) > 0 And rob(n).mem(474) <= 1000 Then 'readmem and memloc couple used to read a specified memory location of the target robot
rob(n).mem(473) = rob(o).mem(rob(n).mem(474))
'rob(n).mem(474) = 0
End If
If rob(o).Fixed Then 'reffixed. Tells if a viewed robot is fixed by .fixpos.
rob(n).mem(477) = 1
Else
rob(n).mem(477) = 0
End If
rob(n).mem(825) = rob(n).venom
rob(n).mem(827) = rob(n).poison
End Sub
Note. In future when entering new lines of code, just comment out the old ones until you are sure you will never need them again. :D
-
Ok, I downloaded the sourcecode again and started over. I made the changes in the robots module as PY mensioned in this topic. After that I got the overflow again.
Code:
rob(n).mem(refvelup) = (rob(o).vx * Cos(rob(n).aim) + rob(o).vy * Sin(rob(n).aim) * -1) - rob(n).mem(velup)
This was supposed to have been fixed by making the changes in the robots module, right? Looks like that's not enough.
-
Can yuo hover-find the values of the varaibles again?
-
Can't remember if you listed it before but what exactly is rob(o)
Is it a corpse?
-
Can yuo hover-find the values of the varaibles again?
Sorry. I have to run a simulation again first and wait for another crash. Looks like the code line must be marked with yellow for the value pop-ups to appear. I'll be back.
-
No it doesn't have to be yellow. It just has to be in debug mode which you enter on a crash.
When it breaks again, don't restart. There are loads of diagnostic stuff we can do while it is in debug mode.
-
You can also enter debug mode by going to VB and hitting pause, but this won't help if you're bug hunting because the code might be (and probably will be) just fine and without error.
-
And it also breaks in the wrong place and won't give access to variables by mouse hovering.
A better way is to set a break point in the routine where you want to debug.
Still no good if all the values are perfectly within normal parameters though. That is why I go into another routine (one which calls the one I want to debug), break it there with a break point, then modify values from the immediate window. Hit the go button to continue past the break point then see if you can force a crash in the routine that you are trying to debug.
That was the way I checked the Maxspeed, shell, mass and so forth earlier.
-
YAY!!!!!! :D
I managed to recreate the error by running corpses in pond mode with Bouyancy turned on.
Now to hit the debug tools.
(cracks knuckles)
-
You can set a line to break on by going o it with your mouse and hitting F9. A red circle will appear beside it to tell you it's now a beak line.
-
You can set a line to break on by going o it with your mouse and hitting F9. A red circle will appear beside it to tell you it's now a beak line.
Never tried it that way.
Easier just to left click with the mouse in the left magin next to the line where you want code execution to break.
-
YAY!!!!!! :D
I managed to recreate the error by running corpses in pond mode with Bouyancy turned on.
Now to hit the debug tools.
(cracks knuckles)
Graaah! I SUSPECTED there were something different with how we run the simulations. Try this settings file out and see what you get.
After you've loaded the settings file you need to manually change the following the the values I use, because they don't get saved in the settings file:
General tab:
Waste Treshold: 100
Boyancy: Checked
Corpse mode: Enabled
Repopulation cooldown period: 10
NRG/veggie/cycle: 10
Right after I've started the sim I enter mutations tab and change to 32x, then I lower it one step every 5000 cycles. I want to start with large diversity and later on let the natural selection decide wich bots survives. Never get very far though.
-
OK the weirdness begins.
First the offending robot o is not a corpse. Second, it is fixed so it isn't even moving even though its .vy is showing 66085.34.
Pretty fast for a bot that is rooted to the spot don't you think? :blink:
What is even weirder is that after tracing where the call to "Lookoccur" comes from, I found it comes from the very top of "Writesenses" (senses module) before any manipulation of variable could take place.
Tracing back further shows the call to "Writesenses" comes from "Updatepos" (Robots module)
A few lines up "Updatepos" I find this chunk of code.
If .mem(216) <> 0 Then
.Fixed = True
.vx = 0
.vy = 0
Else
This sets .fixed to true (as it is in the offending rob(o)). It sets both .vx and .vy to zero also
You know what is missing? :D
Something to reset .vx and .ax if the bot is already fixed.
The code I examined earlier (updatepos in the physics module) doesn't do this. Here it is again
If t <> moving And Not rob(t).Fixed Then
Maxspeed = 30 / (.mass / 2) 'Set maximum speed. Absolute max = 60
You see it specifically excludes fixed robots from this entire calculation routine to save processing time.
We have two choices.- remove "And Not Rob(t).Fixed" from this line of code
- Add another little catch all condition in "Updatepos" to make sure that .vx and .vy are set to zero if a robot is fixed
I think the latter will run faster
find this section of code in "Updatepos"
If .mem(216) <> 0 Then
.Fixed = True
.vx = 0
.vy = 0
Else
.Fixed = False
End If
and change it to
If .mem(216) <> 0 Then
.Fixed = True
Else
.Fixed = False
End If
if .Fixed then
.vx = 0
.vy = 0
Endif
That should hopefully put this problem to bed once and for all.
-
After applying this fix, I had to restart the sim since a huge number of the bots had screwed up memories with massive values in them. While it is possible to repair them one by one as the program runs, I got sick of doing so after the first 30 or so. :rolleyes:
-
Wich window is the above mensioned code supposed to go?
Oh, the robots module! :)
-
Tracing back further shows the call to "Writesenses" comes from "Updatepos" (Robots module)
That one. As I said before.
Sorry if I wasn't being explicit enough. I thought I was. :(
-
Just one more thing before you leave!
This fix is instead of the other ones mensioned in this topic, right, or should those be aplied as well?
-
find this section of code in "Updatepos"
If .mem(216) <> 0 Then
.Fixed = True
.vx = 0
.vy = 0
Else
.Fixed = False
End If
and change it to
If .mem(216) <> 0 Then
.Fixed = True
Else
.Fixed = False
End If
if .Fixed then
.vx = 0
.vy = 0
Endif
The two are logically identical (that is, they both do the same thing).
-
The other fixes aren't hurting anything, so they can be kept or dropped, it doesn't matter.
-
Actually the hovering over the values again was so I could see if it was breaking in the same old way or in a new way.
-
velocity is always going to be <= 32000 beacuse they're stored in ints.
What you want to check is that it's <= MaxVel (which is 60 in 2.37.4)
-
Maybe velocity is stored as longs?
Still shouldn't be > 60.
-
After 1 h 20 min I got the run-time error 6 again.
PY's solution above didn't work, as none of the solutions so far. We need something new to try, I think.
OFEENDING CODE:
rob(n).mem(refveldx) = (rob(o).vy * Cos(rob(n).aim) + rob(o).vx * Sin(rob(n).aim)) - rob(n).mem(veldx)
Location: Senses module at line 481.
HOVERING INFO:
rob(n).mem(refveldx) = 14660
n = 381
refveldx = 697
rob(o).vy = 53168,43
o = 456
rob(n).aim = 5,700001
rob(o).vx = 21,39198
rob(n).mem(veldx) = 2460
veldx = 198
-
It's gonna crash, Griz. Just you wait! :evil:
-
[QUOTEdid you put it in an try it yet?
Yep, I did. If you go back a little in this topic you see that I've posted that I still get the run-time error 6 overflow.
-
code a hard limit rob(o).vx and .vy to 60 right before the crash.
I'm sort of in a rush in the moment (going to SixFlags tomorrow, hve to drive 3.5 hours to get there) so I can't produce the code to do it, but that should do it.
-
You're talking about reproducing the crash here, right? I guess that's for you developers. I don't need to force the program to crash. lol :lol:
-
No I mean before the lines that cause it to crash.
-
I don't understand what you are talking about. Either you're talking about reproducing the crash; why should I do that, or either you're talking about preventing the crash; if so I don't understand how exactly to put that value above the offending code line you're suggesting.
-
Well, since the line is after the crash, I don't see it making a difference.
I can't remember if it should be commented out or not. When I started here months ago *.vel was returning an incorrect value. THat may be a relic from way back then.
-
I tried Griz' example. Didn't change anything for me. Got the same crash after 9 min. No freezing. just same old run-time error 6.
-
Yes, it's commented out here in my version too.
Ok, now both Nums and PY is gone for awhile. I guess I'll leave this alone and go back to my adventure in Neverwinter Nights for the rest of the weekend. By the way, happy birthday, griz. Goodnight folks.
-
find this section of code in "Updatepos"
If .mem(216) <> 0 Then
.Fixed = True
.vx = 0
.vy = 0
Else
.Fixed = False
End If
and change it to
If .mem(216) <> 0 Then
.Fixed = True
Else
.Fixed = False
End If
if .Fixed then
.vx = 0
.vy = 0
Endif
The two are logically identical (that is, they both do the same thing).
Actually they aren't quite the same thing.
The first one sets .fixed to true or false depending on the value in the sysvar .fixpos
It also sets .vx and .vy to zero at this point
The second one takes the .vx and .vy resets out of the sysvar conditional and resets them whenever .fixed is true since it is quite possible for .fixed to be true without the corresponding sysvar value.
Take veggies that are fixed from the GUI or bots that are fixed due to Altzheimers
-
With rob(n)
.mass = 1 + (.body / 10000) + (.Shell / 200) 'set value for mass
Maxspeed = 30 / (.mass / 2) 'Set maximum speed. Absolute max = 60
Absaccel = 0 'reset acceleration
If Abs(.vx) > 32000 Then .vx = 32000 * Sgn(.vx)
If Abs(.vy) > 32000 Then .vy = 32000 * Sgn(.vy)
.absvel = Cos(.aim) * .vx * -1 + Sin(.aim) * .vy 'formula changed to give velocity in the direction robot is facing rather
than always a positive number. Make *.vel work properly.
with:
With rob(n)
If .Shell < 0 Then .Shell = 0
If .body < 0 Then .body = 0: .Dead = True
.mass = 1 + (.body / 10000) + (.Shell / 200) 'set value for mass
Maxspeed = 30 / (.mass / 2) 'Set maximum speed. Absolute max = 60
Absaccel = 0 'reset acceleration
If Abs(.vx) > 32000 Then .vx = 32000 * Sgn(.vx)
If Abs(.vy) > 32000 Then .vy = 32000 * Sgn(.vy)
.absvel = Cos(.aim) * .vx * -1 + Sin(.aim) * .vy 'formula changed to give velocity in the direction robot is facing rather
than always a positive number. Make *.vel work properly.
???
btw ... I just commented out the old code ... just in case. wink.gif
This is in the physics module right?
Then it won't work.
The reason is that for any robot that is fixed, this entore routine is skipped.
If the code in this routine is actually executed then it works perfectly every time without the added limits. No matter what values of .vx and .vy come in here, they always come out at less than Maxspeed (60)
If you want this routine to work, take out the conditional at the top which excluded fixed bots. Then you don't even need to add lines of code. This was answer one in my previous options.
-
The root cause of all this crap is that rob(o) or the robot being viewed, has a velocity of some huge number.
It only happens when rob(o) is fixed
The cause is that somewhere down the line, the accelerations are just being added to a fixed bot and velocity is not being reset.
Answer. Reset all .vx, .vy, .ax and .ay variables for all fixed bots on every cycle
If my previous fix didn't work I think it may have been because it wasn't resetting accelerations but was only resetting velocities. Accelerations are added to current velocities later in the program cycle so if accelerations continue to grow, then eventually we are going to add one that pushes velocity out of bounds.
That would explain how my previous fix allowed the program to run for longer before crashing since it wasn't compounding the error on each cycle.
Try this instead.
If .mem(216) <> 0 Then
.Fixed = True
.vx = 0
.vy = 0
Else
.Fixed = False
End If
and change it to
If .mem(216) <> 0 Then
.Fixed = True
Else
.Fixed = False
End If
if .Fixed then
.vx = 0
.vy = 0
.ax = 0
.ay = 0
Endif
-
Looks like we're not gonna find a solution any time soon, eh?
RUN-TIME ERROR 6: OVERFLOW
OFFENDING CODE:
:shoot: rob(n).mem(refvelup) = (rob(o).vx * Cos(rob(n).aim) + rob(o).vy * Sin(rob(n).aim) * -1) - rob(n).mem(velup)
HOVERING INFO:
rob(n).mem(refvelup) = 0
n = 794
refvelup = 699
rob(o).vx = 0
o = 800
rob(n).aim = 5,91204
rob(o).vy = 210549,3
rob(n).mem(velup) = 7980
velup = 200
I added a picture to show how the simulation looked like when it crash. maybe it whould give someone a hint, I don't know.
-
Well, it's any of those codes in that routine, choices at random. I'm quite sure it's the pond mode that is causing it.
My suggestion is: either get rid of 'Pond mode' (whould be a little boring I think) or make it work!
-
find this section of code in "Updatepos"
If .mem(216) <> 0 Then
.Fixed = True
.vx = 0
.vy = 0
Else
.Fixed = False
End If
and change it to
If .mem(216) <> 0 Then
.Fixed = True
Else
.Fixed = False
End If
if .Fixed then
.vx = 0
.vy = 0
Endif
The two are logically identical (that is, they both do the same thing).
Actually they aren't quite the same thing.
The first one sets .fixed to true or false depending on the value in the sysvar .fixpos
It also sets .vx and .vy to zero at this point
The second one takes the .vx and .vy resets out of the sysvar conditional and resets them whenever .fixed is true since it is quite possible for .fixed to be true without the corresponding sysvar value.
Take veggies that are fixed from the GUI or bots that are fixed due to Altzheimers
To me it seems that they are identical in effect (not in implementation obviously). Try walking trhough it manually with different values for different things and see if you can provide a case where they're not. I could just be a little sleepy.
-
You guys, if desperate, can actually comment out the lines that are crashing. They provide information to the bots but don't hurt the simulation if mising.
Some bots (mostly mine) won't work without it, but many bots will. Dominator Invincibalis for one.
-
What does that code do for the bots anyway. Whouldn't want to comment out something that whould cripple the bots or make them less advanced or something.
Right now I don't see any use for the program as I can't load a saved sim or insert a bot that's been autosaved. Can't evolve bots if I have to start over with a new simulation all the time. I think maybe that worked in version 2.36.7, but you don't have the sourcecode for that version, do you?
-
Windiff over on the downloads section at bottom. Allows you to select diff pages and find changes between them.
-
The one in downloads is actually better than the standard one that comes with VB because it ignores capitalization differences.
I modified it myself ;)
-
Regarding the change I made to the code by separating out the acceleration resets and .fixed stuff.
If .mem(216) <> 0 Then
.Fixed = True
.vx = 0
.vy = 0
Else
.Fixed = False
End If
and change it to
If .mem(216) <> 0 Then
.Fixed = True
Else
.Fixed = False
End If
if .Fixed then
.vx = 0
.vy = 0
Endif
Numsgil answered
To me it seems that they are identical in effect (not in implementation obviously). Try walking trhough it manually with different values for different things and see if you can provide a case where they're not. I could just be a little sleepy.
I agree totally. In terms of code the two would appear to be exactly the same. In practice though they don't seem to be. I often find this with VB.
by putting break points in both conditionals I have caught my new conditional in a true state without the first one running at all.
I can't explain why because this is logically impossible. Nevertheless it happened. :blink:
And that is why I made this change. VB is weird!
-
OK I just got the same damn crash again.
This time rob(o) is NOT fixed.
Every other time it has been but not now.
Looks like I may have been on the wrong track all along with this.
Welcom to the world of debugging programs. :)
Do you see why Num and I take so long to get this stuff sorted now? It isn't easy.
Back to the drawing board again. Please ignore all previous fixes on this thread as none of them really hit the root cause of this problem.
Some of the workarounds that Num posted will get the program running but they don't address the true problem that is causing all this.
I hate workarounds but DB is full of them. :angry:
-
I take it all back.
My fix DID work.
This time the offending robot changed from a fixed normal robot to a corpse during the cycle in which the program crashed.
By doing this it managed to bypass both of the velocity control loops in the program during its first cycle as a corpse.
The bugger found a loophole :blink:
I have plugged it and am waiting to see if it finds another one.
The modification is right at the top of "updpos" in the "physics" module.
I changed
With rob(t)
If t <> moving and not .fixed Then
Maxspeed = 30 / (.mass / 2) 'Set maximum speed. Absolute max = 60
to
With rob(t)
If t <> moving Then
Maxspeed = 30 / (.mass / 2) 'Set maximum speed. Absolute max = 60
This line of code was deliberately preventing fixed robots from having the velocity limits applied to them. After all they aren't moving so why would they need it.
No more loophole now.
-
I'd leave them in, if for no other reason than that they don't hurt the program.
-
The resetting of ax, ay, vx and vy aren't bandaids. they are a necessary and integral part of the program.
Fixes that check the value of stuff directly before acyually using it ARE bandaids and as Nums says, they are at worst doing no harm other than to add a tiny bit of time to the program cycle.
Personally I would like to get rid of all bandaid fixes and get to the root of each problem but often that is extremely tricky to do.
I am now at 40,000 cycles since the last fix and going strong.
Damn this is slow. About 4 cycles per second with all graphics off.
-
You can do like 2.4 does and havea the compiled version save the sim when it crashes.
Then you can load that into VB front end and find the crash.
-
Confused?
Bet you are. I was when the same old bug came back to bite my ass again.
I ran test after test to figure out what was going on and at every step, the main loop of the program kept the active robot's velocity values in check.
Then I suddenly had a thought. :idea:
The problem always occurs in the robot that isn't active when the loop goes to "lookoccur".
But how can that be?
ALL robots go through the main loop so ALL robots should be limited by the software in those loops.
But what if one of the robots has its velocity modified after it has been through the main loop? It would not be subject to the speed limits. If it went through several times then .vx and .vy could get pretty huge.
Then I went searching for how that could happen. here is what I found
subroutine "Repel" in the "physics" module, accelerates two robots away from each other after a collision. If rob(a) has already passed through the main loop but is then crashed into by rob(B) then the resultant acceleration applied to rob(a) could feasibly push it's .vx and .vy to very large numbers without any check.
Put in a couple of break point to find out what was going on and sure enough both robots are leaving the collision with velocities in the hundreds or thousands on almost every collision. The active robot has this sorted in the main loop but the other doesn't. If the other happens to be fixed then it get even worse since it was never reduced to a managable value at all (prior to my other fixes). It just compounded with each cycle.
here is the code for the entire subroutine.
' gives to too near robots an accelaration towards
' opposite directions, inversely prop. to their distance
Private Sub repel(k As Integer, t As Integer)
Dim d As Single
Dim dx As Integer
Dim dy As Integer
Dim dxlk As Single
Dim dylk As Single
Dim dxlt As Single
Dim dylt As Single
Dim kconst As Single
Dim llink As Single
Dim accel As Long 'new acceleration to apply
Dim difKE As Long
Dim maxcel As Single
Dim angl1 As Single
Dim angl2 As Single
Dim colldist As Integer
Dim totx As Single 'total x velocity
Dim toty As Single 'total y velocity
Dim totv As Single 'total absolute velocity
Dim totaccel As Single
Dim decell As Single
Dim kmovx As Single
Dim kmovy As Single
Dim tmovx As Single
Dim tmovy As Single
Dim kKE As Single
Dim tKE As Single
Dim kxm As Single 'robot k x momentum
Dim kym As Single 'robot k y momentum
Dim txm As Single 'robot t x momentum
Dim tym As Single 'robot t y momentum
Dim xmean As Single 'Mean of both x momentums
Dim ymean As Single 'Mean of both y momentums
Dim totKE As Single
Dim kPer As Single 'percentage of acceleration to give to robot k based on mass
Dim tPer As Single 'same for robot t
Dim moveaway As Single 'The amount to directly move a robot away from a collision
'If xmoveaway(k, t) Then GoTo bypass2
'If ymoveaway(k, t) Then GoTo bypass2
dx = (rob(t).x - rob(k).x)
dy = (rob(t).Y - rob(k).Y)
colldist = RobSize + (rob(k).body / factor + rob(t).body / factor) 'amount of overlap based on size of robot
d = Sqr(dx ^ 2 + dy ^ 2) + 0.01 'inter-robot distance
decell = 1
maxcel = 40
'GoTo bypass2
kKE = rob(k).mass * rob(k).vx + rob(k).mass * rob(k).vy
tKE = rob(t).mass * rob(t).vx + rob(t).mass * rob(t).vy
kxm = rob(k).mass * rob(k).vx 'rob(k) x momentum signed
kym = rob(k).mass * rob(k).vy 'rob(k) y momentum signed
txm = rob(t).mass * rob(t).vx 'rob(t) x momentum signed
tym = rob(t).mass * rob(t).vy 'rob(t) y momentum signed
xmean = (Abs(kxm) + Abs(txm)) / 2 'absolute mean of x momentums. Both counted as positive
ymean = (Abs(kym) + Abs(tym)) / 2 'absolute mean of y momentums. Both counted as positive
If rob(k).mass = 0 Then rob(k).mass = 0.01
rob(k).vx = rob(k).vx + (xmean / rob(k).mass) * kxColdir(k, t) * decell
rob(t).vx = rob(t).vx + (xmean / rob(t).mass) * txColdir(k, t) * decell
rob(k).vy = rob(k).vy + (ymean / rob(k).mass) * kyColdir(k, t) * decell
rob(t).vy = rob(t).vy + (ymean / rob(t).mass) * tyColdir(k, t) * decell
bypass2:
'totKE = tKE + kKE 'calculates total momentum of both robots
'difKE = kKE - tKE 'difference in momentum
'tPer = rob(k).mass / (rob(k).mass + rob(t).mass) 'percentage of total momentum in bot k
'kPer = rob(t).mass / (rob(k).mass + rob(t).mass) 'percentage of total momentum in bot t
'If rob(k).vx = 0 Then rob(k).vx = 0.00001
'If rob(t).vx = 0 Then rob(t).vx = 0.00001
'mvanglt = Atn(rob(k).vy / rob(k).vx)
'mvangla = Atn(rob(t).vy / rob(t).vx)
'angledifference = angnorm(AngDiff(mvanglt, angl))
'exitangle = angnorm(angl - angledifference)
'newvx = (rob(k).vx + rob(t).vx) * (rob(t).mass / (rob(k).mass + rob(t).mass))
'newvy = (rob(k).vy + rob(t).vy) * (rob(t).mass / (rob(k).mass + rob(t).mass))
'newvx = newvx * 0.95
'newvy = newvy * 0.95
'llink = 1000
'totx = Abs(rob(k).vx) + Abs(rob(t).vx)
'totx = rob(k).vx + rob(t).vx
'toty = Abs(rob(k).vy) + Abs(rob(t).vy)
'toty = rob(k).vy + rob(t).vy
'totv = totx + toty
angl1 = angle(rob(k).x, rob(k).Y, rob(t).x, rob(t).Y) 'angle from rob k to rob t
angl2 = angle(rob(t).x, rob(t).Y, rob(k).x, rob(k).Y) 'angle from rob t to rob k
'colldist = colldist * 1.2
'dxlk = absx(angl1, totKE, 0, 0, 0) * tPer
'dylk = absy(angl1, totKE, 0, 0, 0) * tPer
'dxlt = absx(angl2, totKE, 0, 0, 0) * kPer
'dylt = absy(angl2, totKE, 0, 0, 0) * kPer
'totaccel = Abs(dxl) + Abs(dyl)
'kconst = 0.01
'dxl = (dx - (llink * dx) / d)
'dyl = (dy - (llink * dy) / d)
moveaway = (colldist - d) / 2 'move away based on half of overlap
If d < colldist Then
kmovx = absx(angl1, moveaway, 0, 0, 0)
kmovy = absy(angl1, moveaway, 0, 0, 0)
tmovx = absx(angl2, moveaway, 0, 0, 0)
tmovy = absy(angl2, moveaway, 0, 0, 0)
If Not rob(t).Fixed Then
rob(t).x = rob(t).x - tmovx
rob(t).Y = rob(t).Y - tmovy
End If
If Not rob(k).Fixed Then
rob(k).x = rob(k).x - kmovx
rob(k).Y = rob(k).Y - kmovy
End If
Else
kmovx = 0
kmovy = 0
tmovx = 0
tmovy = 0
End If
bypass3:
End Sub
Add a new limit code in here and hopefully this will fix the problem for good at source instead of patching it. (heard that before somewhere. Wonder where? :rolleyes: )
Maxspeed = 30 / (rob(t).mass / 2)
totv = Sqr(rob(t).vx ^ 2 + rob(t).vy ^ 2)
If totv > Maxspeed Then 'top speed limit routine 2 changed faster speeds for lower mass robots
maxcel = totv / Maxspeed
rob(t).vx = rob(t).vx / maxcel
rob(t).vy = rob(t).vy / maxcel
End If
Maxspeed = 30 / (rob(k).mass / 2)
totv = Sqr(rob(k).vx ^ 2 + rob(k).vy ^ 2)
If totv > Maxspeed Then 'top speed limit routine 2 changed faster speeds for lower mass robots
maxcel = totv / Maxspeed
rob(k).vx = rob(k).vx / maxcel
rob(k).vy = rob(k).vy / maxcel
End If
This is where it goes. Probably easier to just copy the entire routine.
' gives to too near robots an accelaration towards
' opposite directions, inversely prop. to their distance
Private Sub repel(k As Integer, t As Integer)
Dim d As Single
Dim dx As Integer
Dim dy As Integer
Dim dxlk As Single
Dim dylk As Single
Dim dxlt As Single
Dim dylt As Single
Dim kconst As Single
Dim llink As Single
Dim accel As Long 'new acceleration to apply
Dim difKE As Long
Dim maxcel As Single
Dim angl1 As Single
Dim angl2 As Single
Dim colldist As Integer
Dim totx As Single 'total x velocity
Dim toty As Single 'total y velocity
Dim totv As Single 'total absolute velocity
Dim totaccel As Single
Dim decell As Single
Dim kmovx As Single
Dim kmovy As Single
Dim tmovx As Single
Dim tmovy As Single
Dim kKE As Single
Dim tKE As Single
Dim kxm As Single 'robot k x momentum
Dim kym As Single 'robot k y momentum
Dim txm As Single 'robot t x momentum
Dim tym As Single 'robot t y momentum
Dim xmean As Single 'Mean of both x momentums
Dim ymean As Single 'Mean of both y momentums
Dim totKE As Single
Dim kPer As Single 'percentage of acceleration to give to robot k based on mass
Dim tPer As Single 'same for robot t
Dim moveaway As Single 'The amount to directly move a robot away from a collision
'If xmoveaway(k, t) Then GoTo bypass2
'If ymoveaway(k, t) Then GoTo bypass2
dx = (rob(t).x - rob(k).x)
dy = (rob(t).Y - rob(k).Y)
colldist = RobSize + (rob(k).body / factor + rob(t).body / factor) 'amount of overlap based on size of robot
d = Sqr(dx ^ 2 + dy ^ 2) + 0.01 'inter-robot distance
decell = 1
maxcel = 40
'GoTo bypass2
kKE = rob(k).mass * rob(k).vx + rob(k).mass * rob(k).vy
tKE = rob(t).mass * rob(t).vx + rob(t).mass * rob(t).vy
kxm = rob(k).mass * rob(k).vx 'rob(k) x momentum signed
kym = rob(k).mass * rob(k).vy 'rob(k) y momentum signed
txm = rob(t).mass * rob(t).vx 'rob(t) x momentum signed
tym = rob(t).mass * rob(t).vy 'rob(t) y momentum signed
xmean = (Abs(kxm) + Abs(txm)) / 2 'absolute mean of x momentums. Both counted as positive
ymean = (Abs(kym) + Abs(tym)) / 2 'absolute mean of y momentums. Both counted as positive
If rob(k).mass = 0 Then rob(k).mass = 0.01
rob(k).vx = rob(k).vx + (xmean / rob(k).mass) * kxColdir(k, t) * decell
rob(t).vx = rob(t).vx + (xmean / rob(t).mass) * txColdir(k, t) * decell
rob(k).vy = rob(k).vy + (ymean / rob(k).mass) * kyColdir(k, t) * decell
rob(t).vy = rob(t).vy + (ymean / rob(t).mass) * tyColdir(k, t) * decell
Maxspeed = 30 / (rob(t).mass / 2)
totv = Sqr(rob(t).vx ^ 2 + rob(t).vy ^ 2)
If totv > Maxspeed Then 'top speed limit routine 2 changed faster speeds for lower mass robots
maxcel = totv / Maxspeed
rob(t).vx = rob(t).vx / maxcel
rob(t).vy = rob(t).vy / maxcel
End If
Maxspeed = 30 / (rob(k).mass / 2)
totv = Sqr(rob(k).vx ^ 2 + rob(k).vy ^ 2)
If totv > Maxspeed Then 'top speed limit routine 2 changed faster speeds for lower mass robots
maxcel = totv / Maxspeed
rob(k).vx = rob(k).vx / maxcel
rob(k).vy = rob(k).vy / maxcel
End If
bypass2:
'totKE = tKE + kKE 'calculates total momentum of both robots
'difKE = kKE - tKE 'difference in momentum
'tPer = rob(k).mass / (rob(k).mass + rob(t).mass) 'percentage of total momentum in bot k
'kPer = rob(t).mass / (rob(k).mass + rob(t).mass) 'percentage of total momentum in bot t
'If rob(k).vx = 0 Then rob(k).vx = 0.00001
'If rob(t).vx = 0 Then rob(t).vx = 0.00001
'mvanglt = Atn(rob(k).vy / rob(k).vx)
'mvangla = Atn(rob(t).vy / rob(t).vx)
'angledifference = angnorm(AngDiff(mvanglt, angl))
'exitangle = angnorm(angl - angledifference)
'newvx = (rob(k).vx + rob(t).vx) * (rob(t).mass / (rob(k).mass + rob(t).mass))
'newvy = (rob(k).vy + rob(t).vy) * (rob(t).mass / (rob(k).mass + rob(t).mass))
'newvx = newvx * 0.95
'newvy = newvy * 0.95
'llink = 1000
'totx = Abs(rob(k).vx) + Abs(rob(t).vx)
'totx = rob(k).vx + rob(t).vx
'toty = Abs(rob(k).vy) + Abs(rob(t).vy)
'toty = rob(k).vy + rob(t).vy
'totv = totx + toty
angl1 = angle(rob(k).x, rob(k).Y, rob(t).x, rob(t).Y) 'angle from rob k to rob t
angl2 = angle(rob(t).x, rob(t).Y, rob(k).x, rob(k).Y) 'angle from rob t to rob k
'colldist = colldist * 1.2
'dxlk = absx(angl1, totKE, 0, 0, 0) * tPer
'dylk = absy(angl1, totKE, 0, 0, 0) * tPer
'dxlt = absx(angl2, totKE, 0, 0, 0) * kPer
'dylt = absy(angl2, totKE, 0, 0, 0) * kPer
'totaccel = Abs(dxl) + Abs(dyl)
'kconst = 0.01
'dxl = (dx - (llink * dx) / d)
'dyl = (dy - (llink * dy) / d)
moveaway = (colldist - d) / 2 'move away based on half of overlap
If d < colldist Then
kmovx = absx(angl1, moveaway, 0, 0, 0)
kmovy = absy(angl1, moveaway, 0, 0, 0)
tmovx = absx(angl2, moveaway, 0, 0, 0)
tmovy = absy(angl2, moveaway, 0, 0, 0)
If Not rob(t).Fixed Then
rob(t).x = rob(t).x - tmovx
rob(t).Y = rob(t).Y - tmovy
End If
If Not rob(k).Fixed Then
rob(k).x = rob(k).x - kmovx
rob(k).Y = rob(k).Y - kmovy
End If
Else
kmovx = 0
kmovy = 0
tmovx = 0
tmovy = 0
End If
bypass3:
End Sub
It even appears that this has a slight impact on the way that bots collide. Looks a bit more normal to me but then I could be biased.
-
without all this documented in a central place ...
it's very difficult to even find the appropriate threads and purposed fixes.
But it IS documented in one place.
It is all in this thread. Why is that a problem?
-
You can do like 2.4 does and havea the compiled version save the sim when it crashes.
Then you can load that into VB front end and find the crash.
how?
can I easily snag that code from somewhere in 2.44?
It's in the sub function in Form1 I think called "main".
It's like 3 lines of code.
-
[2.4 plug]
Collisions can't produce too large velocities in 2.4 because the accelerations are saved for later
[/2.4plug]
-
OK well as soon as some other people confirm this as working then it can be mvoed to fixed section :D
-
If it works, PY will probably go ahead and release it as 2.37.5 or something. (hint ;))
-
I forget the exact name of the function to be honest. I do know it used the function "frnd".
-
This stuff is all hunky dory now so thread moved to "solved bugs" for posterity. (or posterior if you prefer)
:D