Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accumulate contact points to prevent objects sinking when using ODE - Waiting for comments #1832

Draft
wants to merge 45 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
39a78a8
Add potential fix draft and test case
henriquealrs Jul 6, 2024
f7e4a12
Fix Collision test
henriquealrs Jul 9, 2024
d3aacc4
Remove archlinux support
jslee02 Jun 23, 2024
5976fe6
Remove building archlinux images
jslee02 Jun 23, 2024
a020c50
Upgrade pybind11 to v2.12.0
jslee02 Jun 23, 2024
e8ed6e4
Update changelog for 6.14.0
jslee02 Jun 25, 2024
3a27135
Bump version to 6.15
jslee02 Jun 26, 2024
b4c6db3
Include CTest for BUILD_TESTING option (#1819)
scpeters Jun 26, 2024
bc57e9b
Fix doxygen folder path
jslee02 Jun 26, 2024
9d9d1bc
Replace pagmo with pagmo-devel
jslee02 Jun 27, 2024
b95ff83
[pixi] Fix finding pagmo and ipopt
jslee02 Jun 27, 2024
b631135
[py] Remove binding of deprecated BoxedLcpConstraintSolver constructor
jslee02 Jun 27, 2024
ff610d3
[vcpkg] Update to 2024.06.15
jslee02 Jun 27, 2024
e11c65f
config.hpp.in: remove whitespace from version macros (#1820)
scpeters Jun 28, 2024
69a445c
[vcpkg] Update version to 2024.06.15 for dartpy build
jslee02 Jun 29, 2024
8cf5fa8
[pixi] Exclude hidden folders from formatting
jslee02 Jun 29, 2024
b6a39c4
[clang-format] Set language standard to C++17
jslee02 Jun 29, 2024
eb6fa74
[build] Remove DART_IN_CI
jslee02 Jun 30, 2024
cf86865
[pixi] Use system installed imgui
jslee02 Jun 30, 2024
0a70b7f
[build] Fix Findimgui.cmake -- still not working since libimgui.so do…
jslee02 Jun 30, 2024
6ffb2e4
[vcpkg] Update packages
jslee02 Jun 30, 2024
a55b701
[vcpkg] Use system installed imgui
jslee02 Jun 30, 2024
634d15d
[build] Use Ninja on Unix
jslee02 Jun 30, 2024
a0a1784
[pixi] Rename example- to ex-
jslee02 Jun 30, 2024
34f62f6
[pixi] Run lock update CI job on every Sat
jslee02 Jun 30, 2024
42ad24d
[pixi] Add tutorial tasks
jslee02 Jun 30, 2024
938cd1a
[docker] Update dep versions for dartpy build
jslee02 Jul 1, 2024
433de99
Update pixi lockfile (#1828)
github-actions[bot] Jul 6, 2024
23b52dd
Set DART_ENABLE_SIMD=OFF by default (#1825)
jslee02 Jul 4, 2024
814628a
[docker] Update DART version to 6.15
jslee02 Jul 6, 2024
50adcf2
[ci] Use noble as default
jslee02 Jul 6, 2024
58a8aea
[ci] Add oracular job
jslee02 Jul 6, 2024
654a883
[ci] Use jammy for codecov
jslee02 Jul 7, 2024
094010e
Set DART_BUILD_DARTPY=OFF by default
jslee02 Jul 7, 2024
5a849d1
[py] Remove OpenCL settings in setup.py
jslee02 Jul 8, 2024
2d4dcb5
Merge branch 'main' into Investigate_Issue_1654
henriquealrs Jul 13, 2024
ff26983
Merge branch 'main' into Investigate_Issue_1654
henriquealrs Jul 13, 2024
4651fb6
Fix in solution
henriquealrs Jul 13, 2024
44bc4db
Remove couts
henriquealrs Jul 13, 2024
1026f54
I think I fixed it
henriquealrs Jul 13, 2024
2312d16
Another fix in solution
henriquealrs Jul 14, 2024
9b7a9fe
Merge branch 'main' into Investigate_Issue_1654
henriquealrs Jul 23, 2024
a221386
Clang-format
henriquealrs Jul 23, 2024
aee3429
Fix test
henriquealrs Jul 23, 2024
7ce709a
Merge branch 'main' into Investigate_Issue_1654
jslee02 Dec 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 94 additions & 4 deletions dart/collision/ode/OdeCollisionDetector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "dart/collision/ode/OdeCollisionDetector.hpp"

#include "dart/collision/CollisionFilter.hpp"
#include "dart/collision/Contact.hpp"
#include "dart/collision/ode/OdeCollisionGroup.hpp"
#include "dart/collision/ode/OdeCollisionObject.hpp"
#include "dart/collision/ode/OdeTypes.hpp"
Expand All @@ -49,6 +50,10 @@

#include <ode/ode.h>

#include <deque>
#include <unordered_map>
#include <utility>

namespace dart {
namespace collision {

Expand All @@ -70,6 +75,37 @@ Contact convertContact(
OdeCollisionObject* b2,
const CollisionOption& option);

using CollObjPair = std::pair<CollisionObject*, CollisionObject*>;

struct ContactHistoryItem
{
CollObjPair pair;
std::deque<Contact> history;
ContactHistoryItem() = delete;
};

// using ContactManifold = std::unordered_map<CollObjPair,
// std::deque<Contact>,obj_pair_hash>;
std::vector<ContactHistoryItem> pastContacts;

CollObjPair MakeNewPair(CollisionObject* o1, CollisionObject* o2)
{
return std::make_pair(std::min(o1, o2), std::max(o1, o2));
}

std::deque<Contact>& FindPairInHist(const CollObjPair& pair)
{
for (auto& item : pastContacts) {
if (pair.first == item.pair.first && pair.second == item.pair.second) {
return item.history;
}
}
auto newItem = ContactHistoryItem{pair, std::deque<Contact>()};
pastContacts.push_back(newItem);

return pastContacts.back().history;
}

struct OdeCollisionCallbackData
{
dContactGeom* contactGeoms;
Expand Down Expand Up @@ -161,6 +197,21 @@ bool OdeCollisionDetector::collide(

dSpaceCollide(odeGroup->getOdeSpaceId(), &data, CollisionCallback);

for (auto& past_contact : pastContacts) {
bool clear = true;
for (const auto& curr_result : result->getContacts()) {
auto current_pair = MakeNewPair(
curr_result.collisionObject1, curr_result.collisionObject2);
if (past_contact.pair == current_pair) {
clear = false;
break;
}
}
if (clear) {
past_contact.history.clear();
}
}

return data.numContacts > 0;
}

Expand Down Expand Up @@ -285,8 +336,9 @@ void CollisionCallback(void* data, dGeomID o1, dGeomID o2)

cdData->numContacts += numc;

if (result)
if (result) {
reportContacts(numc, odeResult, collObj1, collObj2, option, *result);
}
}

//==============================================================================
Expand All @@ -305,15 +357,53 @@ void reportContacts(
// without the checkings of repeatidity and co-linearity.
if (1u == option.maxNumContacts) {
result.addContact(convertContact(contactGeoms[0], b1, b2, option));

return;
}

for (auto i = 0; i < numContacts; ++i) {
result.addContact(convertContact(contactGeoms[i], b1, b2, option));
}

auto missing = 3 - numContacts;
if (missing <= 0) {
return;
}

const auto pair = MakeNewPair(b1, b2);
auto& pastContacsVec = FindPairInHist(pair);
auto results_vec_copy = result.getContacts();

for (auto it = pastContacsVec.rbegin(); it != pastContacsVec.rend(); ++it) {
if (missing <= 0)
break;
auto past_cont = *it;
for (const auto& curr_cont : results_vec_copy) {
const auto res_pair
= MakeNewPair(curr_cont.collisionObject1, curr_cont.collisionObject2);
if (res_pair != pair) {
continue;
}
auto dist_v = past_cont.point - curr_cont.point;
const auto dist_m = (dist_v.transpose() * dist_v).coeff(0, 0);
if (dist_m < 0.01) {
continue;
} else {
--missing;
result.addContact(past_cont);
}
}
}
for (const auto& item : results_vec_copy) {
const auto res_pair
= MakeNewPair(item.collisionObject1, item.collisionObject2);
if (res_pair == pair) {
pastContacsVec.push_back(item);
}
}

if (result.getNumContacts() >= option.maxNumContacts)
return;
const auto size = pastContacsVec.size();
if (size > 11) {
pastContacsVec.erase(pastContacsVec.begin(), pastContacsVec.end() - 5);
}
}

Expand Down
8 changes: 4 additions & 4 deletions tests/integration/test_Collision.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -482,10 +482,10 @@ void testSphereSphere(
EXPECT_TRUE(group->collide(option, &result));
// TODO(JS): BulletCollisionDetector includes a bug related to this.
// (see #876)
#if HAVE_BULLET
if (cd->getType() != BulletCollisionDetector::getStaticType())
#endif
{

constexpr auto hasOde = (HAVE_ODE == 1);
constexpr auto hasBullet = (HAVE_BULLET == 1);
if constexpr (!hasOde && !hasBullet) {
EXPECT_EQ(result.getNumContacts(), 1u);
}
for (auto i = 0u; i < result.getNumContacts(); ++i) {
Expand Down
8 changes: 8 additions & 0 deletions tests/regression/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ if(TARGET dart-collision-bullet AND TARGET dart-collision-ode)
dart-utils)
endif()


dart_add_test("regression" test_Issue1654)
target_link_libraries(test_Issue1654
dart-collision-bullet
dart-collision-ode
dart-gui-osg
dart-utils)

if(TARGET dart-utils)
dart_add_test("regression" test_Issue1193)
target_link_libraries(test_Issue1193 dart-utils)
Expand Down
121 changes: 121 additions & 0 deletions tests/regression/test_Issue1654.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2011-2022, The DART development contributors
* All rights reserved.
*
* The list of contributors can be found at:
* https://github.com/dartsim/dart/blob/master/LICENSE
*
* This file is provided under the following "BSD-style" License:
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include <dart/gui/osg/osg.hpp>

#include <dart/utils/DartResourceRetriever.hpp>

#include <dart/simulation/World.hpp>

#include <dart/constraint/ConstraintSolver.hpp>

#include <dart/collision/bullet/BulletCollisionDetector.hpp>
#include <dart/collision/ode/OdeCollisionDetector.hpp>

#include <dart/dynamics/BoxShape.hpp>
#include <dart/dynamics/FreeJoint.hpp>
#include <dart/dynamics/MeshShape.hpp>
#include <dart/dynamics/PlaneShape.hpp>
#include <dart/dynamics/Skeleton.hpp>
#include <dart/dynamics/WeldJoint.hpp>

#include <TestHelpers.hpp>
#include <gtest/gtest.h>

#include <cstring>

using namespace dart;

class CapsuleTest : public testing::Test,
public testing::WithParamInterface<const char*>
{
};
TEST_P(CapsuleTest, CapsuleCollision)
{
const double capsuleRadius = 0.2;
const double capsuleHeight = 0.6;

auto world = dart::simulation::World::create();

if (strcmp(GetParam(), "bullet") == 0) {
world->getConstraintSolver()->setCollisionDetector(
dart::collision::BulletCollisionDetector::create());
} else if (strcmp(GetParam(), "ode") == 0) {
world->getConstraintSolver()->setCollisionDetector(
dart::collision::OdeCollisionDetector::create());
} else {
ASSERT_TRUE(false);
}

auto ground = createBox({10000, 1000, 0.1}, {0, 0, -0.05});
ground->setMobile(false);
world->addSkeleton(ground);

::osg::ref_ptr<gui::osg::RealTimeWorldNode> node
= new gui::osg::RealTimeWorldNode(world);

auto skeleton = dart::dynamics::Skeleton::create("test");
dart::dynamics::FreeJoint* joint;
BodyNode* bn;
std::tie(joint, bn)
= skeleton->createJointAndBodyNodePair<dart::dynamics::FreeJoint>();

Eigen::Isometry3d T_capsule;
T_capsule = Eigen::Translation3d(0, 0, 0.5)
* Eigen::AngleAxisd(M_PI_2, Eigen::Vector3d(0, 1, 0));
joint->setRelativeTransform(T_capsule);

auto capsuleNode = bn->createShapeNodeWith<
dart::dynamics::CollisionAspect,
dart::dynamics::DynamicsAspect>(
std::make_shared<dart::dynamics::CapsuleShape>(
capsuleRadius, capsuleHeight));

dart::dynamics::Inertia inertia;
inertia.setMass(1.0);
inertia.setMoment(capsuleNode->getShape()->computeInertia(inertia.getMass()));
bn->setInertia(inertia);
// std::cout << "Inertia: " <<
// bn->getBodyNodeProperties().mInertia.getMoment()
// << std::endl;

world->addSkeleton(skeleton);
const double tolerance = 0.05;
for (int i = 1; i < 50000; ++i) {
world->step();
auto capsulePos = bn->getWorldTransform().translation();
ASSERT_GT(capsulePos.z(), capsuleRadius - tolerance);
}
}

INSTANTIATE_TEST_CASE_P(CollisionEngine, CapsuleTest, testing::Values("ode"));
// testing::Values("bullet", "ode"));
Loading