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.