ODE Internal Error 1: Assertion "bNormalizationResult" funk

1,378 views
Skip to first unread message

Entropy

unread,
Oct 29, 2008, 5:42:54 AM10/29/08
to ode-users
Greetings. I am getting:

ODE INTERNAL ERROR 1: assertion "bNormalizationResult" failed in
_dNormalize3() [../../include/ode/odemath.h]

when using ODE and colliding a trimesh. Below is a stack trace:

#0 0xb71b0c87 in raise () from /lib/libc.so.6
#1 0xb71b24f8 in abort () from /lib/libc.so.6
#2 0xb651986b in dDebug (num=1,
msg=0xb661a7dc "assertion \"bNormalizationResult\" failed in %s()
[%s]")
at error.cpp:103
#3 0xb6547e12 in _dNormalize3 (a=0x931e590) at ../../include/ode/
odemath.h:314
#4 0xb654912f in dCollideSTL (g1=0x931d1f8, SphereGeom=0x931d508,
Flags=32,
Contacts=0x931e580, Stride=116) at collision_trimesh_sphere.cpp:
436
#5 0xb6509592 in dCollide (o1=0x931d508, o2=0x931d1f8, flags=32,
contact=0x931e580, skip=116) at collision_kernel.cpp:280
#6 0xb78263d0 in OgreOde::Geometry::collide (this=0x9304228,
geometry=0x8df5578, listener=0x8496dc8) at OgreOdeGeometry.cpp:340
#7 0xb7838111 in OgreOde::World::collisionCallback (data=0x0,
geom_a=0x931d508, geom_b=0x931d1f8) at OgreOdeWorld.cpp:194
#8 0xb650ffe6 in collideAABBs (g1=0x931d508, g2=0x931d1f8, data=0x0,
callback=0xb7838020 <OgreOde::World::collisionCallback(void*,
dxGeom*, dxGeom*)>) at collision_space_internal.h:81
#9 0xb651193e in dxHashSpace::collide (this=0x84c01c8, data=0x0,
callback=0xb7838020 <OgreOde::World::collisionCallback(void*,
dxGeom*, dxGeom*)>) at collision_space.cpp:589
#10 0xb65108e1 in dSpaceCollide (space=0x84c01c8, data=0x0,
callback=0xb7838020 <OgreOde::World::collisionCallback(void*,
dxGeom*, dxGeom*)>) at collision_space.cpp:775
#11 0xb7833771 in OgreOde::Space::collide (this=0x0, data=0x0)
at OgreOdeSpace.cpp:78
#12 0xb7835d51 in OgreOde::StepHandler::basicStep (this=0x84bfec8,
time=4.99999987e-06) at OgreOdeStepper.cpp:113
#13 0xb7836dde in OgreOde::StepHandler::step (this=0x84bfec8,
time=4.99999987e-06) at OgreOdeStepper.cpp:157
#14 0x0807254b in excor::Physics::frame (this=0x8496dc8, usTime=5)
at Physics.cpp:51
#15 0x0805c6e0 in excor::Engine::run (this=0x81482a0) at Engine.cpp:
134
#16 0x080e71bd in main () at main.cpp:30

I've started digging around the source code and would like to draw
some attention to some code I don't quite understand. In
collision_trimesh_sphere.cpp at line 363 we have the following code:

dReal Depth;

Which declares some form of contact depth. Cool, continuing on...Line
369 has us doing this.

if (Depth < REAL(0.0)){
Depth = REAL(0.0);
}

Essentially we zero the Depth if it's less than zero. The problem is
later how we use this zeroed depth. Line 395 has:

Contact->depth = Depth * dirProj;

Which, if Depth was subject to the previous condition makes Contact-
>depth zero. Line 409 begins as:

Contact->normal[0] *= Contact->depth;
Contact->normal[1] *= Contact->depth;
Contact->normal[2] *= Contact->depth;
Contact->normal[3] *= Contact->depth;

So if Depth was zeroed, and so was Contact, our entire Contact->normal
is zero. Line 436 is where the bomb goes off:

dNormalize3(Contact->normal);

Trying to normalise a normal vector which is made up of all zeroes
causes the assertion issue. Any ideas, suggestions? Why are we zeroing
the depth?

Daniel K. O.

unread,
Oct 29, 2008, 6:35:25 AM10/29/08
to ode-...@googlegroups.com
Entropy escreveu:

> dReal Depth;
>
> Which declares some form of contact depth. Cool, continuing on...Line
> 369 has us doing this.
>
> if (Depth < REAL(0.0)){
> Depth = REAL(0.0);
> }

This seems useless. "Depth" is obtained from GetContactData's "Dist",
computed with this code:

Dist = dSqrt(dFabs(DistSq));

if (Dist <= Radius){
Dist = Radius - Dist;
return true;
}
else return false;

Radius is positive, Dist is non-negative. If Dist <= Radius, the
subtraction can never be negative. So the test "if (Depth < 0)" will
never be triggered. I believe GetContactData should return false when
the depth is zero too.

Could you try changing the above "<=" test to "<", and see if it solves
your problem? Or even better, if you have a test case we can try out.


--
Daniel K. O.
"The only way to succeed is to build success yourself"

Oleh Derevenko

unread,
Oct 29, 2008, 6:40:35 AM10/29/08
to ode-...@googlegroups.com
Thank you. Fixed.

Oleh Derevenko
-- ICQ: 36361783


----- Original Message -----
From: "Entropy" <tom.gau...@gmail.com>
To: "ode-users" <ode-...@googlegroups.com>
Sent: 29 жовтня 2008 р. 11:42
Subject: [ode-users] ODE Internal Error 1: Assertion "bNormalizationResult"
funk


>
> Greetings. I am getting:
>
> ODE INTERNAL ERROR 1: assertion "bNormalizationResult" failed in
> _dNormalize3() [../../include/ode/odemath.h]
>
> when using ODE and colliding a trimesh. Below is a stack trace:
>
> #0 0xb71b0c87 in raise () from /lib/libc.so.6
> #1 0xb71b24f8 in abort () from /lib/libc.so.6
> #2 0xb651986b in dDebug (num=1,
> msg=0xb661a7dc "assertion \"bNormalizationResult\" failed in %s()
> [%s]")
> at error.cpp:103
> #3 0xb6547e12 in _dNormalize3 (a=0x931e590) at ../../include/ode/
> odemath.h:314
> #4 0xb654912f in dCollideSTL (g1=0x931d1f8, SphereGeom=0x931d508,
> Flags=32,
> Contacts=0x931e580, Stride=116) at collision_trimesh_sphere.cpp:
> 436

...


Daniel K. O.

unread,
Oct 29, 2008, 7:29:14 AM10/29/08
to ode-...@googlegroups.com
Oleh Derevenko escreveu:
> Thank you. Fixed.

But thinking more carefully, why should zero-depth contact points be
illegal?

The error seems to lie in the "ifdef MERGECONTACTS" block; don't use
normals from zero-depth contacts in the merging step (because their
weight is proportional to their depth).

Oleh Derevenko

unread,
Oct 29, 2008, 7:38:26 AM10/29/08
to ode-...@googlegroups.com
Zero depth contacts are not illegal. They are just useless and can be
ignored. It is like bodies being touching but not applying any force to each
other. Zero penetration is a marginal value which can be produced by
algorithms due to imprecise numeric comptations. If bodies just touch, you
can with the same level of confidence assume that there is a contact and
that there is no contact. Adding or ignoring such contacts should not affect
the physics of the system.

Oleh Derevenko
-- ICQ: 36361783


----- Original Message -----
From: "Daniel K. O." <danielk...@gmail.com>
To: <ode-...@googlegroups.com>
Sent: 29 жовтня 2008 р. 13:29
Subject: [ode-users] Re: ODE Internal Error 1: Assertion
"bNormalizationResult" funk


>

Daniel K. O.

unread,
Oct 29, 2008, 7:56:32 AM10/29/08
to ode-...@googlegroups.com
Oleh Derevenko escreveu:

> It is like bodies being touching but not applying any force to each
> other. Zero penetration is a marginal value which can be produced by
> algorithms due to imprecise numeric comptations.

Not if I place the sphere there, to be in contact with the triangle.

Other than maybe "it's too much work", I don't why we shouldn't handle
this case. I'll try to come up with the proper fix later.

Oleh Derevenko

unread,
Oct 29, 2008, 8:12:27 AM10/29/08
to ode-...@googlegroups.com
Could you explain, what is the use of zero-depth contact? If objects will
continue motion towards the penetration, there will be a normal positive
depth contact on next world step. If objects just touch each other and move
apart, why that event just can't be left unnoticed? You can consider the
later case as if there was still a very small distance between the objects
and they did not actually touch.

The nature of floating point computations does not allow you to just "place
the sphere there, to be in contact with the triangle". You can place a
sphere of integer radius at integer coordinates and touch a triangle at
different integer coordinates. But if there would be a space transformation
or objects would be moved to the positions farther from origin, the equality
would no longer be true. Due to computational errors, you get either a tiny
penetration or a tiny gap between the objects. Therefore you should never
rely on exact match with floating point numbers.

Also, if MERGECONTACTS is defined, that dummy contact will affect
Contact->pos merging but will not affect Contact->normal, which looks like
an inconsistency to me.

Oleh Derevenko
-- ICQ: 36361783


----- Original Message -----
From: "Daniel K. O." <danielk...@gmail.com>
To: <ode-...@googlegroups.com>
Sent: 29 жовтня 2008 р. 13:56
Subject: [ode-users] Re: ODE Internal Error 1: Assertion
"bNormalizationResult" funk


>

Daniel K. O.

unread,
Oct 29, 2008, 11:38:00 AM10/29/08
to ode-...@googlegroups.com
Oleh Derevenko escreveu:

> Could you explain, what is the use of zero-depth contact?

More precision is never a bad thing.

> If objects will
> continue motion towards the penetration, there will be a normal positive
> depth contact on next world step.

Yes, but I'm talking about the collision detection part.


> The nature of floating point computations does not allow you to just "place
> the sphere there, to be in contact with the triangle".

Yes, I can. And I wrote a test case for it. As long as I have a sqrt()
implementation that gives exact answers for powers-of-two.


> Also, if MERGECONTACTS is defined, that dummy contact will affect
> Contact->pos merging but will not affect Contact->normal, which looks like
> an inconsistency to me.

Not any more inconsistent than the original code; near-zero depth also
means it will contribute little to the averaged normal, but will
contribute as much as any other point over the position. Maybe that part
too should use the depths as weights?

But anyway, I just avoided computing the new normal over the original;
if the accumulated normal is <= dEpsilon, the first contact normal is used.

Oleh Derevenko

unread,
Oct 29, 2008, 1:51:15 PM10/29/08
to ode-...@googlegroups.com
----- Original Message -----
From: "Daniel K. O."

>> Could you explain, what is the use of zero-depth contact?
> More precision is never a bad thing.

In my opinion, it is not more precision, just more uncertainty.


>> If objects will
>> continue motion towards the penetration, there will be a normal positive
>> depth contact on next world step.
>
> Yes, but I'm talking about the collision detection part.

You can consider that there was a computational error and your zero-depth
collision has not been detected. And indeed, it will not be detected from
time to time.

N.B.: I've removed normalization for normal in case the merged depth is less
than dEpsilon and normal is not assigned. Original normals of individual
contacts should be already normalized.

Gonçalo Lopes

unread,
Nov 22, 2008, 1:27:38 PM11/22/08
to ode-users
Hi all,

I'm having this exact same problem. Apparently, the proposed fix
addresses the OPCODE collision detection, but I'm having the same
issue using the GIMPACT functions. I've tried searching the code for
the correct place to apply the equivalent fix, but failed. Where
should I put the fixes so that GIMPACT collision does not suffer from
the same issue?

Cosmetics aside, I think this case should be handled, if only to stop
ODE from non-deterministically terminating the application with a
popup.

Best regards and thanks for everything,

Gonçalo

Oleh Derevenko

unread,
Nov 22, 2008, 1:52:29 PM11/22/08
to ode-...@googlegroups.com
Hi Gonçalo

Please update to the latest revision, capture the assertion failure in a
debugger and post the stack trace through the ODE here.

Oleh Derevenko
-- ICQ: 36361783


----- Original Message -----
From: "Gonçalo Lopes"
To: "ode-users"
Sent: 22 листопада 2008 р. 20:27
Subject: [ode-users] Re: ODE Internal Error 1: Assertion
"bNormalizationResult" funk



Gonçalo Lopes

unread,
Nov 22, 2008, 2:30:37 PM11/22/08
to ode-...@googlegroups.com
Thanks for the help.

I've just noticed that apparently this isn't a collision detection
issue anymore, since it's failing on the world step method, apparently
when normalizing the body quaternion.

Any idea how can this happen? Singularities?

I'll check tag version 0.10.1 since there I was pretty sure it was a
collision detection error.

Anyway, here is the stacktrace in WinDbg format.

ChildEBP RetAddr Args to Child
0338d0c0 7e419418 7e42dba8 00000000 00000000 ntdll!KiFastSystemCallRet
WARNING: Stack unwind information not available. Following frames may be wrong.
0338d0f8 7e42593f 0019186a 00000000 00000001 USER32!WaitMessage+0xc
0338d120 7e43a91e 7e410000 00218cd0 00000000 USER32!DrawStateW+0x1f2
0338d3e0 7e43a284 0338d53c 00000000 ffffffff USER32!SoftModalMessageBox+0x677
0338d530 7e4661d3 0338d53c 00000028 00000000 USER32!MessageBoxIndirectA+0x23a
0338d588 7e466278 00000000 0550c4f8 04123e10 USER32!MessageBoxTimeoutW+0x7a
0338d5bc 7e450617 00000000 0338d74c 0338d6e0 USER32!MessageBoxTimeoutA+0x9c
0338d5dc 7e4505cf 00000000 0338d74c 0338d6e0 USER32!MessageBoxExA+0x1b
*** WARNING: Unable to verify checksum for
D:\Projects\YDreams\YLabs\InteractiveSurfaces\Trunk\Source\YDreams.InteractiveSurfaces.Standalone\bin\Release\ode_singled.dll
0338d5f8 092e24df 00000000 0338d74c 0338d6e0 USER32!MessageBoxA+0x45
0338db48 0931775d 00000001 09334764 093347a0 ode_singled!dDebug+0xbf
[d:\projects\ydreams\ylabs\odenet\trunk\source\externals\ode\ode\src\error.cpp
@ 158]
0338dc38 093172fc 08e65a04 0338ede0 0338e060
ode_singled!_dNormalize4+0x4d
[d:\projects\ydreams\ylabs\odenet\trunk\source\externals\ode\include\ode\odemath.h
@ 321]
0338de70 093043e2 08e65928 3dcccccd cccccccc
ode_singled!dxStepBody+0x40c
[d:\projects\ydreams\ylabs\odenet\trunk\source\externals\ode\ode\src\util.cpp
@ 267]
0338ede0 09317bdb 08e646d8 0338eee0 00000001
ode_singled!dxQuickStepper+0x14b2
[d:\projects\ydreams\ylabs\odenet\trunk\source\externals\ode\ode\src\quickstep.cpp
@ 842]
0338f078 092ff103 08e646d8 3dcccccd 0929082a
ode_singled!dxProcessIslands+0x39b
[d:\projects\ydreams\ylabs\odenet\trunk\source\externals\ode\ode\src\util.cpp
@ 375]
0338f158 05a6617d 08e646d8 3dcccccd e44091b8
ode_singled!dWorldQuickStep+0x83
[d:\projects\ydreams\ylabs\odenet\trunk\source\externals\ode\ode\src\ode.cpp
@ 1645]
0338f1dc 79e71b4c 01355648 00000000 0338f284 0x5a6617d
0338f1f0 79e821b1 0338f2c4 00000001 0338f290 mscorwks+0x1b4c
0338f270 79e96501 0338f2c4 00000001 0338f290
mscorwks!DllUnregisterServerInternal+0x6195
0338f3b8 79e96534 792546dc 0338f514 0338f410 mscorwks!CoUninitializeEE+0x2e95
0338f3d4 79e96552 792546dc 0338f514 0338f410 mscorwks!CoUninitializeEE+0x2ec8

Best regards,

Gonçalo


2008/11/22 Oleh Derevenko <od...@eleks.lviv.ua>:

Oleh Derevenko

unread,
Nov 22, 2008, 2:52:37 PM11/22/08
to ode-...@googlegroups.com
Unfortunately, I'm only familiar with collision detection code and did not
dig into the physics simulation. Maybe someone else could be of assistance
with this.

Gonçalo Lopes

unread,
Nov 22, 2008, 7:33:41 PM11/22/08
to ode-...@googlegroups.com
My system keeps crashing with Assertion "bNormalizationResult"
failures. The problem is that I need to keep dynamic trimesh geoms
which have their shapes updated every frame (destroyed and recreated).

I admit that this may introduce odd singularities with the collision
detection + contact joint system. I got it to a point where mostly it
seems pretty stable and smooth, collision-wise, but suddenly,
out-of-the-blue, a bNormalizationResult appears on dWorldQuickStep().

Anyone knows what are the usual symptoms for this error and the
possible workarounds?

I've increased both contact and global CFM values so far and tried
approaching masses and lengths to unity.

I understand the difficulties with controlling physics integrators,
but it's frustrating to have a perfectly good-looking simulation
suddenly crashing out of nowhere. It's not even a case of growing
instability. Everything looks perfectly stable and smooth until
eventually, it just crashes.

Best regards and thanks in advance for all your help,

Gonçalo Lopes

unread,
Nov 22, 2008, 7:59:05 PM11/22/08
to ode-...@googlegroups.com
Ok, I think I got it. I had to bring my masses and lengths even closer
to unity. It's amazing how sensible the integrator is in the 0.1...10
range. It's a world of difference. I've managed to stop the crashes so
far. I'll let you know of the results.

I guess it was just a matter of "taming the beast".

Thanks for everything,

Gonçalo


2008/11/23 Gonçalo Lopes <goncal...@gmail.com>:

Reply all
Reply to author
Forward
0 new messages