Skip to content

DART 6.20.0

Latest

Choose a tag to compare

@jslee02 jslee02 released this 11 Oct 17:04
· 90 commits to main since this release
de2514e

DART 6.20.0 is a minor release on the DART 6 line focused on contact-heavy performance. The 3,000-shape scene from #3056, run in a headless simulation host with the ODE detector, completes 18.9x faster than with DART 6.19.4, and every body comes to rest and sleeps instead of sinking through the ground. The default FCL detector now collides exact primitive shapes, more resting scenes fall asleep and wake when they should, the opt-in dart collision detector becomes a complete backend, and two opt-in friction solvers are available. The release is not ABI compatible with 6.19: read Breaking Changes and Behavior Changes before upgrading. The milestone linked below lists every merged change.

Breaking Changes

  • Rebuild all code that links against DART. The library SONAME is now libdart.so.6.20, and Skeleton, World, MemoryManager and SimpleFrame (plus ShapeNode and SoftBodyNode in AVX builds) change layout. The SimpleFrame change fixes a crash when it is constructed with GCC 16, or with AVX code generation on older GCC (#3447, #3504, #3552, #3627, #3632)

  • dartpy is built with pybind11 3.x. Rebuild extension modules that pass dartpy objects across the Python/C++ boundary against the same pybind11 release (#3344, #3643)

  • Six components are removed. Drop them from find_package(DART COMPONENTS ...) and migrate code that includes their headers:

    • gui, the GLUT viewer, including dart/gui/glut and gui.hpp: use gui-osg.
    • optimizer-ipopt, optimizer-nlopt and optimizer-pagmo, with the multi-objective API, the dart.optimizer.NloptSolver binding and the HAVE_IPOPT, HAVE_NLOPT, HAVE_PAGMO and HAVE_SNOPT macros: use the dart-optimization package. The optimizer core used by inverse kinematics remains.
    • external-lodepng, with GLUT screenshots: use the OSG viewer's capture support.
    • external-odelcpsolver: a native Dantzig solver replaces it, and the dart/lcpsolver/dantzig/*.h forwarders remain.

    The header-only dart/external/convhull_3d and dart/integration are removed too; use math::computeConvexHull3D and World::step() (#3076, #3088, #3105, #3116, #3122)

  • dart/config.hpp no longer defines DART_BUILD_MODE_DEBUG or DART_BUILD_MODE_RELEASE; test NDEBUG instead. DART's debug-only checks now follow NDEBUG rather than the build type, and the unused BoxedLcpSolver::canSolve() is removed (#3627)

  • Source builds need GCC 11.2, Clang 13, Apple Clang 14 (Xcode 14.1) or Visual Studio 2022, on Ubuntu 22.04, macOS 13 or newer, and dartpy needs Python 3.10 and NumPy 1.21.5 or newer. The build requirements list the dependency versions (#3643)

  • The build stops when FCL uses a single-precision libccd (libccd's default), which causes momentum drift on shallow contacts. Rebuild libccd with -DENABLE_DOUBLE_PRECISION=ON and FCL against it, or configure with -DDART_ALLOW_SINGLE_PRECISION_LIBCCD=ON (#3590, #3630)

Behavior Changes

These change simulation results without any code change.

  • FCLCollisionDetector, the default detector, now collides supported primitive shapes as exact FCL primitives (PRIMITIVE) instead of mesh approximations, with corrected contact normals. The default constraint solver and the SKEL parser follow. Select MESH or the fcl_mesh detector for the previous behavior (#3131)

  • Sleeping (on by default since 6.19) covers more resting scenes: islands that use a custom BodyNodeCollisionFilter can now sleep, and imported worlds whose bodies start at rest on level supports settle within their first steps. A stricter quiet check keeps slowly creeping bodies awake, so a settling body falls asleep later than in 6.19, about 0.5 s later for a box dropped onto a floor. As in 6.19, each island sleeps independently of other moving bodies and wakes on contact. Set DeactivationOptions::mEnabled to false for always-active simulation, or DART_CUSTOM_FILTER_SLEEPING=0 to keep custom-filter islands awake (#3086, #3112, #3565, #3632, #3683)

  • When a step needs more contacts than CollisionOption::maxNumContacts allows, the cap is now shared across the colliding pairs. Detection used to stop at the cap, so the pairs found last got no contacts and their bodies fell through their support. Scenes that stay under the cap are unchanged; with more colliding pairs than the cap, some pairs still get no contacts, so raise the cap if bodies sink (#3551)

  • Collision objects for shapes added after World::addSkeleton() are created in subscription order, so such scenes are reproducible across runs; their trajectories change once (#3607)

  • The ODE detector adds the support contact it misses for a cylinder resting on a plane, so settled cylinders join their island and can sleep (#3203)

  • BulletCollisionDetector drops contacts with negative penetration depth by default. Set CollisionOption::allowNegativePenetrationDepthContacts to keep these proximity hits (#3136)

Performance

  • Large contact-heavy worlds run much faster: in a headless simulation host with the ODE detector and one physics thread, the 3,000-shape scene from #3056 completes 3 simulated seconds 18.9x faster than with DART 6.19.4, mostly because its bodies now settle and sleep early. Awake steps are cheaper too: contact constraints are reused across steps and built in parallel, single-body contact groups assemble their LCP directly, and steps where every island rests reuse cached state (#3140, #3142, #3146, #3147, #3149, #3151)

  • The ODE detector looks up contact-history and contact pairs through sorted indexes: an awake 3,000-body step runs about 30% fewer instructions on a PlaneShape ground and about 20% fewer on a box ground, with bit-exact results (#3574)

  • MetaSkeleton::getPositions() takes about a quarter fewer instructions, and the other DOF getters and setters are faster too, with unchanged results (#3554)

  • Add opt-in multithreading: World::setNumSimulationThreads(), also in dartpy, solves independent constraint islands and builds contacts in parallel. Custom constraints, contact handlers and LCP solvers, and bodies shared across islands, keep the serial path (#3071, #3111, #3149)

  • Add opt-in allocation-free stepping: after World::enterSimulationMode() or the first step, scenes that use the dart detector and keep the same shapes step without heap allocations. Preparing a world keeps its sleep state and does not call custom contact surface handlers (#3297, #3549, #3563, #3587, #3615)

And more

The full changelog also covers new collision, constraint, simulation, dynamics, parser, Python, GUI, example, math and build changes.


Full changelog: https://github.com/dartsim/dart/blob/v6.20.0/CHANGELOG.md - Milestone: https://github.com/dartsim/dart/milestone/99?closed=1