1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
|
@@@'s
TODO for COLLISION
------------------
box-box collision: adjust generated face-face contact points by depth/2 to
be more fair.
what happens when a GeomTransform's encapsulated object is manipulated,
e.g. position changed. should this be disallowed? should a GeomTransform
behave like a space and propagate dirtyness upwards?
make sure that when we are using a large space for static environmental geoms,
that there is not excessive AABB computation when geoms are added/removed from
the space. the space AABB is pretty much guaranteed to cover everything, so
there's no need to compute/test the AABB in this case.
hash space: implement collide2() efficiently instead of the current
simple-space-like brute-force approach.
hash space: incremental scheme, so we dont have to rebuild the data structures
for geoms that don't move.
disabled geoms (remove from all collision considerations) ... isn't this the
same as just taking it out of its enclosing group/space?
integrate:
dRay
triangle collider - get latest tri collider code from erwin
erwin's quadtree space
tests:
all aspects of collision API
dGeomSetBody(0) maintains body-geom linked list properly.
simple space: instantiate lots of non-moving geoms (i.e. environmental
geoms and make sure that we're still able to collide efficiently.
make sure AABB computation is efficient, or can be made efficient
through proper use of the API.
test C interface support for making new classes.
make sure the dxGeom::aabbTest() function behaves as advertised.
testing for contact point consistency: test for things that
would cause the dynamics to fail or become unstable
test for: small adjustment in geom position causes a big jump in the
contact point set (bad for dynamics).
test for: if contact constraints observed then it's impossible
(or hard) to move the objects so that the penetration is
increased. relax this when only a subset of the contact points are
returned.
test for consistency, e.g. the boundary of geoms X and Y can
be defined by intersecting with a point, so test the intersection of X
and Y by comparing with the point tests.
check that contact points are in the collision volume
all existing space tests, and more.
demos:
test_buggy: make a terrain out of non-moving geoms. use heirarchical
groups to get efficient collision, even with the simple space.
go though the new collision docs and make sure the behavior that is described
there is actually implemented.
multi-resolution hash table:
the current implementation rebuilds a new hash table each time
collide() is called. we don't keep any state between calls. this is
wasteful if there are unmoving objects in the space.
make sure we prevent multiple collision callbacks for the same pair
better virtual address function.
the collision search can perhaps be optimized - as we search
chains we can come across other candidate intersections at
other levels, perhaps we should do the intersection check
straight away? --> save on list searching time only, which is
not too significant.
collision docs:
optimization guide: whenever a single geom changes in a simple space,
the space AABB has to be recomputed by examining EVERY geom.
document this, or find a better behavior.
TODO BEFORE NEXT RELEASE
------------------------
g++ needed for compiling tests using gcc 3.2 ? what is the problem?
add joint feedback info from lambda, so that we can get motor forces etc.
need a way to map constraint indexes to what they mean.
track down and fix the occasional popping/jumping problem in test_boxstack,
especially when boxes are piled on top of each other. find out if this is
caused by a configuration singularity or whether there is a bug in LCP.
i need to add some kind of diagnostic tool to help resolve these kinds of
problems.
fixup ground plane jitter and shadow jumping in drawstuff.
the inertias/COMs don't appear to be totally correct for the boxstack demo.
fix up, and add a mode that shows the effective mass box (for a given density).
Improve box-box collision, especially for face-face contact (3 contact points).
Improve cylinder-box collision (2 contact points).
windows DLL building and unix shared libs. libtool?
also MSVC project files.
dBodyGetPointVel()
contrib directory - all stuff in ~/3/ode
functions to allow systems to be copied/cloned
dBodyTransplant (b, world)
dTransplantIsland (b, world)
dBodyCopy (bdest, bsrc)
dJointCopy (jdest, jsrc) -- what about body connections?
dCloneBody()
dCloneJoint()
dCloseBodyAndJointList()
dCloneIsland()
this collision rule:
// no contacts if both geoms on the same body, and the body is not 0
if (g1->body == g2->body && g1->body) return 0;
needs to be replaced. sometimes we want no collision when both bodies are 0,
but this wont work for geomgroup-to-environment. avoid stupid stuff like
dGeomSetBody (geom_group, (dBodyID) 1);
this also causes "failed-to-report" errors in the space test.
Expose type-specific collision functions?
Automatic code optimization process.
joint limit spongyness: interacts with powered joints badly, because when the
limit is reached full power is applied. fix or doc.
various hinge2 functions may not function correctly if axis1 and axis2 are not
perpendicular. in particular the getAngle() and getAngleRate() functions
probably will give bogus answers.
slow step function will not respect the joint getinfo2 functions calling
addTorque() because it reads the force/torque accumulators before the
getinfo2 functions are called.
spaces need multiple lists of objects that can never overlap. objects in these
lists are never tested against each other.
deleting a body a joint is attached to should adjust the joint to only have
one body attached. currently the connected joints have *both* their body
attachments removed. BUT, dont do this if the dJOINT_TWOBODIES flag is set
on the joint.
document error, mem and math functions.
Web pages
credits section
projects using ODE
update C++ interface? use SWIG?
collision exclusion groups - exclude if obj1.n == obj2.n ?
make sure the amotor joint can be used with just one body. at the moment it
only allows two-body attachments.
implement dJointGetAMotorAngleRate()
erwin says: Should the GeomGroup have a cleanupmode as the GeomTransform has?
erwin says: http://q12.org/pipermail/ode/2002-January/000766.html
and http://q12.org/pipermail/ode/2001-December/000753.html
rename duplicate filenames (object.h?) - some environments can't handle this.
naming inconsistency: dCreateSphere() should be dSphereCreate() (etc...) to
match the rest of the API.
TODO
----
joint allocation in joint groups. allocation size should be rounded up using
dEFFICIENT_SIZE, to properly align all the data members.
all dAlloc() allocations should be aligned using dEFFICIENT_SIZE() ???
automatic body & joint disabling / enabling.
sometimes getting LCP infinite loops.
function to get the entire island of bodies/joints
joints:
hinge2 joint - implement trail, i.e. non-convergent steering and wheel
axes.
erp individually settable for each joint?
more joints:
angular3 (constrian full angle not position)
fixed path 1 (point must follow fixed path, etc etc)
- other fixed path joints.
linear a (point in 1 body fixed to plane of other)
linear b (point in 1 body fixed to line on other)
linear c (line in 1 body fixed to plane on other)
linear d (line in 1 body fixed to line on other) - like
prismatic but orientation along line can change
Relative-Path-Relative-Oriention Joint (set all dofs of 2
bodies relative to each other)
spring (with natural length)
universal (2 kinds)
various angular relationships
when attaching joints to static env, provision to move attachment
point (e.g. give it a linear/angular velocity). this can be used
instead of a FPFO joint on a body in many cases.
also do this with contacts to static env, to allow for contacts to
*moving* objects in the static env.
interpretation of erp: is it (1) the error reduction per timestep,
(2) or a time constant independent of timestep?? if it's (2) then
perhaps this should be universal - this is already the meaning for
the suspension.
hinge2 suspension:
suspension limits
suspension limit restitution and spongyness??
use autoconf? set paths in makefile?
no-arg init functions, for andy
explore: do joint parameters need to be set for the joint to be setup
correctly, or should set some proper body-dependent params when it is
attached? this is only really an issue for joints that have no parameters to
set, such as the fixed joint.
dAlloc() should take an arena parameters which is stored in dWorld.
debugging mode should use dASSERT2 that prints a descriptive error message
on error, not just the file:line or function. use dASSERT for internal
consistency checking.
when vectors and matrices are initialized, we must ensure that the padding
elements are set to 0. this is going to be a problem everywhere!
don't use 3-vectors anywhere. use SIMD friendly 4-vectors.
make sure all data in body/joint etc objects is aligned well for single
precision SIMD (i.e. all vectors start on a 16 byte boundary).
think about more complicated uses of collision, e.g. a single geom representing
an articulated structure.
bodyGroup? (like joint group but for bodies). systemGroup?
check the overhead of resizing Array<>s as elements are pushed on to them.
replace alloca() with dPushFrame(), dPopFrame(), and dAlloca() ? allow for
the possibility of allocating in non-stack memory ?
make sure that we can set mass parameters with non-zero center of mass.
if this is done after the body position is set, the position is adjusted.
if this is done before the body position is set, what do we do when the
pos is set? does the pos always refer to the center of mass from the user's
point of view?
consider splitting solver into functions, which can be optimized separately.
might make things go faster.
faster code for islands with a single body? faster code for dynamically
symmetric bodies?
rotation.cpp functions that set matrices should also set padding elements.
lcp solver must return (L,d) and some other information, so we can re-solve
for other right hand sides later on, but using the same complimentarity
solution so there are no integrator discontinuities.
dSetZero() - make fast inline functions for fixed n e.g. (1-4).
need proper `sticky' friction, i.e. compensation for numerical slip.
on windows, make sure gcc-compiles libs can be linked with VC++ apps. need
to make sure some C++ runtime bits are present?
kill all references to dArray<> (in geom.cpp).
need testing code to test all joints with body-to-static-env
copy stack.cpp, memory.cpp stuff to reuse
dFactorLDLT() is not so efficient for matrix sizes < block size, e.g.
redundant calls, zero loads, adds etc
contacts: cheaper friction: viscous friction? one step delay friction force.
in geom.cpp, for objects that are never meant to collide, dCollide() will
always try to find the collider functions, which wastes a bit of time.
geom.cpp:dCollideG() - handle special case of colliding 2 groups more
efficiently.
timer reporting function:
void timerReport (void (*printFunction)(char *, ...));
disabled bodies stored in a separate list, so they are never traversed at all,
for speed when there are many disabled bodies.
MAYBE
-----
new implementation for joint groups that is not so system dependent.
maybe individual contacts are reusable? in this case contact information
should be settable in the contact joints. max_size arg is really annoying.
consider making anchor,axis, (everything) into a joint parameter and setting
them with a consistent interface. also consider overload the joint functions
so they are not distinguished by joint type??
collision memory optimizations?
collision: support for persistent contact information?
multiply reference tri list data so that it can be cloned
if the tri-list geoms could support rot/pos
transformations then we could have several tri-lists pointing to the
same vertex information.
height fields
pre-converted collision data -- Creating a hash space and associated
opcode tree structures may take significant amounts of time for a
large world with many 10s of thousands of triangles. Any chance of
pre-building that off-line and passing a memory block pointer to the
collision system?
putting objects in multiple spaces -- If it was possible to add
objects to more than one space, you could do collision queries other
than 1vsN and NvsN. That flexibility might be useful when you want to
only collide against a subset of the space. For example, a camera
system may want to collide some rays with occlusion walls but the
occlusion walls may also need to be in the game-level space to bounce
against.
ALWAYS
------
make sure functions check their arguments in debug mode (e.g. using dASSERT).
make sure joint/geom functions check for the specific object type.
vectors alloca()ed on the stack must have the correct alignment, use ALLOCA16.
library should have no global constructors, as it might be used with C linkage.
use `const' in function arguments. blah.
DON'T BOTHER
------------
warning if user tries to set mass params with nonzero center of mass.
DONE
----
check: when contact attached with (body1,0) and (0,body1), check that polarity
on depth and error info is okay for the two cases.
set a better convention for which is the 1st and 2nd body in a joint, because
sometimes we get things swapped (because of the way the joint nodes are used).
hinge and prismatic, attachment to static environment.
turn macros into C++ inline functions? what about C users?
remove `space' argument to geom creation functions? make user add it?
or just remove it from dCreateGeom() ? <-- did this one.
test_chain should be in C, not C++. but first must remove global constructors.
add more functionality to C++ interface - dMass, dSpace, dGeom
there should be functions to delete groups of bodies/joints in one go - this
will be more efficient than deleting them one at a time, because less
partitioning tests will be needed.
should we expose body and joint object structures so that the user can
explicitly allocate them locally, or e.g. on the stack? makes allocating
temporary contact constraints easier. NO --> helps data hiding and therefore
library binary compatability.
joints:
hinge & slider - DONE
measure angle, rate - DONE
power - DONE
joint limits - DONE
mixed powered+limited joints, powering away from limit - DONE
hinge2 - DONE
steering angle and rate measurement - DONE
steering limits - DONE
steering motor - DONE
wheel motor - DONE
wheel angle rate measurement - DONE
optional hinge2 suspension: - DONE
alignment of B&S part to given axis - DONE
global framework for giving epsilon and gamma - DONE
toss away r-motor, make power & stuff specific to joint - DONE
it's just easier that way
joint code reuse: - DONE
use standard functions to set velocity (c), limits (lo,hi),
spongyness (epsilon) etc, this prevents these functions from
proliferating
implicit spring framework - actually allow joints to return a value `k'
such that J*vnew = c + k*f, where f = force needed to achieve
vnew - DONE
contact slip - DONE
contact erp & cfm parameters (not just "softness") - DONE
hinge2: when we lock back wheels along the steering axis, there is no
error correction if they get out of alignment - DONE, just use high
and low limits.
joint limit spongyness: erp and cfm for joint set from world (global)
values when joint created. - DONE
joint limit restitution - DONE
check inertia transformations, e.g. by applying steering torque to a thin
wheel --> actually, i made test_I
more comprehensive random number comparisons between slow and fast methods.
- random PD inertia (not just diagonal).
- random velocity
- random joint error (make joints then move bodies a bit)
check that J*vnew=c (slow step already does this, but it doesn't equal zero
for some reason! - actually, when LCP constraint limits are reached, it wont!)
tons of things in lcp.cpp (@@@), especially speed optimizations. also, we
wanted to do index block switching and index block updates to take advantage
of the outer product trick ... but this is not worth the effort i think.
lcp.cpp: if lo=hi=0, check operation. can we switch from NL <-> NH without
going through C? --> done.
andy says: still having trouble with those resource files..
drawstuff.res doesn't seem to build or be found under cygwin gcc.
DOC how bodies and geoms associated then resolved in contact callback ... not
really necessary.
fix the "memory leak" in geom.cpp
library should have no global constructors, as it might be used with C linkage.
--> as long as test_chain1 works, there are none.
DOC cfm, the derivation and what it means.
--> partially done, could be better
joint "get type" function
andy says: in ode/src/error.cpp _snprintf() and _vsnprintf() are missing
in testode: finite and isnan are missing. copysign is missing
russ: okay here's the problem: i have Makefile.platform files for
VC++, MinGW, but not Cygwin. Cygwin uses the unix-like functions
for everything, but the VC++/MinGW configs assumes the MS C-runtime
functions. this is easy to fix, except i need to install Cygwin
which is a pain to do over MinGW. argh.
build on linux - assumptions made about location of X11 lib, opengl etc.
implement: dBodyAddForceAtPos,dBodyAddRelForceAtPos,dBodyAddRelForceAtRelPos,
dBodyGetPointPos,dBodyGetPointVel,dBodyGetPointRelVel
dJointAttach(), allow both bodies to be 0 to put the joint into limbo.
space near-callback should be given potentially intersecting objects 100 at a
time instead of 1 at a time, to save on calling costs ... which are trivial,
so we don't bother to do this.
doccer: @func{} also refs second etc function in function *list*.
make sure joints can return 0 from GetInfo1, i.e. no constraints or "inactive"
joint, and the step functions will handle it.
when attaching contact with (0,body), instead of setting the reverse flag
on the joint and checking it in getInfo2(), we should just reverse the normal
straight away ... ?
--> trouble is, dJointAttach() knows nothing about what kind of joint
it is attaching.
hinge2 needs to be attached to two bodies for it to work, make sure this is
always the case. --> assertion added in dJointAttach().
if two joints connect to the same two bodies, check that the fast solver
works! -> it should.
functions to get all the joints/bodies a body/joint is connected to.
If I don't have the GCC libraries installed, HUGE_VALF is undefined.
fix capped cylinder - capped cylinder collision so that two contacts can
be generated.
transformation geometry object.
joint groups should also be destroyed by destroying the world --> naaahhh.
DONT DO THIS: body/joint creators with world = 0 --> not inserted into any
world. allow bodies/joints to be detached from a world (this is what happens
to grouped joints when a world is destroyed).
can bodies and joints be linked together when not attached to world??
what happens when we have an island of b/j, some of which are not in
world? soln: dont keep lists of b/j in the world, just infer it from
the islands?
body & joint disabling / enabling
start a change log.
collision flags - 0xffff mask.
dBodyGetFiniteRotationMode() / ...Axis()
dBodyAddForceAtRelPos()
ball & socket joint limits and motors.
auto-build env on windows: 3 compilers, debug/release, short/double =
12 combinations --> auto logs.
handle infinities better: HUGE_VALF is not commanly defined, it seems.
get rid of the __USE_ISOC9X macro in common.h
perhaps just use a "big" number instead of the actual IEEE infinity, it's
more portable anyway.
--> new config system
dCloseODE() - tidy up *all* allocated memory, esp in geom.cpp. used to keep
leak detectors happy.
extra API to get lambda and J'*lambda from last timestep.
better stack implementation that is not so system dependent. but how will
we do dynamic page allocation? do we even need to?
all collision files will now be collision_*, not geom_*
check exported global symbols - no C++ mangling.
rename dSphere etc to dxSphere etc.
C interface support for making new classes.
make sure DLL-ized stuff preserved ... but class numbers should no longer be
exported.
point geom ( = sphere of radius 0 )
geoms stored in doubly linked lists in space (fast removal).
bodies need to keep geoms pointers and call dGeomMoved() in dBodySetPosition()
etc and world step. PROBLEM: links dynamics and collision together too much,
makes it hard to extract ODE collision ... unless we say: dGeomMoved() and
dGeomID must be supplied by the new collision library!
dCollide() should take spaces as arguments - it should call dSpaceCollide2()
with its own callback that puts all found contacts in the array, stopping
when there is no more space left in the array.
dxSpace::getGeom() - the geom numbers will change as geoms are dirtied - find
some other numbering scheme, or document this behavior.
the 'placeable' property - objects that should not ever be attached to bodies
should flag an error when setBody etc are called.
dGeomSetBody(0) - DOC: the position and orientation of the body will be
preserved. in this case the geom should NOT be dirtied (dGeomMoved() should
not be called).
DOC: dGeomGetBodyNext() as part of dynamics/collision interface
groups/spaces are subclasses of geom.
groups/spaces can contain other groups/spaces. geom can be owned by a
group/space. collision handling:
geom-geom : standard collision function
geom-group : special space code
group-group : n^2 tests (or n space tests) - hard to optimize because
of disjoint space representations.
group internal : normal space internal-collision code
groups/spaces can be told that some objects never move, i.e. that the objects
are locked. should we lock the whole space?
locking: the AABB for the object is not recalculated
groups/spaces can be told that the internal contents self-intersect or not.
actually an old ODE group is the equivalent of an old ODE simple space.
- just call dCollide() or not.
the group doesn't get passed to the space callback any more ... only the
intersecting geoms get passed? maybe the callback can initiate the extra
intersection tests itself? (because we want programmable flexibility to
determine what gets intersected and what doesn't)
- NO
infrastructure to indicate when an object has moved (and thus its AABB needs
to be recalculated)
space enumeration functions. make sure that there are no additions or deletions
while enumeration is taking place.
- documented the behavior, didn't disallow it
cache the AABB in the dxGeom? (for non-moving objects) - perhaps keep a
pointer to separately allocated space? ... no
DOC: dGeomGetClass() is a first-class geom function, not in the "User
defined classes" section. it returns a constant that can be checked
against dSphereClass etc.
remove dxGeom dependence on dBodyID? ... not yet
dBase -> dxBase
allow a geom to be inserted into multiple spaces? need this to optimize some
kinds of tests ... no
update docs.
make CHECK_NOT_LOCKED an assert.
DOC: "Calling these functions on a non-placeable geom results in a
runtime error." ...in the debug build only?
non-placeable geoms should not allocate dxPosR. perhaps pass a dGeom
constructor arg that says 'placeable' or not - this also sets the
GEOM_PLACEABLE flag.
GeomTransform:
final_pos and final_R valid if no GEOM_AABB_BAD flag!!!
fix up this code, esp use of ComputeTX().
Space incompatibilities: no dSpaceDestroy(), dGeomDestroy() does not
take a dSpaceID ... dSpaceDestroy() added.
GeomGroup incompatibilities:
dCollide() used to take a GeomGroup and would return all the contact
points for all the intersecting objects. now you have to call
dSpaceCollide2() and get a callback for each one.
need to provide old behavior.
simple space optimization: we should keep the precomputed AABB for the
non-moving geoms around, so that when the other geoms move we can just
compute the AABBs for those geoms and then combine it with the non-moving AABB.
--> too hard!
collision build options: old and new
tidyups for collision:
* rationalize what stuff goes in what source files, and file names
* minimize set of header files that all collision* sources use - after
all changes.
* update ode-cpp stuff (C++ interface header files).
porting guide:
ODE list email
dGeomGetSpaceAABB() deleted
dGeomGetClass (geom_group); used to return a unique type for
GeomGroups, but now it returns dSimpleSpaceID.
tidyups: update DLL declarations.
|