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

Testable Constraint Output #266

Merged
merged 52 commits into from
Jan 7, 2018
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
3fcb61f
Added TestableOutcomeClass.
evil-sherdil Nov 26, 2017
46ed3d8
Added NonCollidingOutcome.hpp
evil-sherdil Nov 26, 2017
4dfa900
Include TestableOutcome in Testable. Fix TestableOutcome to make it w…
evil-sherdil Nov 26, 2017
9368a14
Updated Testable isSatisfied signature and changed *bunch* of signatu…
evil-sherdil Nov 26, 2017
235e0da
Changed NonCollidingOutcome name to reflect CollisionFree name change…
evil-sherdil Nov 26, 2017
98ef161
Started CollisionFreeOutcome.cpp. Small changed to make it build once…
evil-sherdil Nov 26, 2017
9c36bae
Wrote toString for CollisionFreeOutcome.
evil-sherdil Nov 26, 2017
62af07b
Made CollisionFree fill _outcome on a collision (if not nullptr).
evil-sherdil Nov 26, 2017
081e23e
Fixed test files to make tests build. Will run make format in just a …
evil-sherdil Nov 27, 2017
d28417c
Added testing for CollisionFreeOutcome.
evil-sherdil Nov 27, 2017
faffb52
Use move semantics in CollisionFreeOutcome toString method.
evil-sherdil Nov 27, 2017
3ecb343
Ran make format.
evil-sherdil Nov 27, 2017
a276c6a
Merge branch 'master' into sniyaz/feature/testableConstraintOutput
jslee02 Nov 27, 2017
c281a03
Adressed nits from @jslee02. Moving to squish those unused param warn…
evil-sherdil Nov 28, 2017
f83c72a
Merge branch 'sniyaz/feature/testableConstraintOutput' of https://git…
evil-sherdil Nov 28, 2017
9863a86
Merge branch 'master' into sniyaz/feature/testableConstraintOutput
brianhou Nov 28, 2017
924041b
Silence unused param warning, ran make format again.
evil-sherdil Nov 28, 2017
a4a0309
Used dynamic_cast in CollisionFree when populating outcome fields. Ba…
evil-sherdil Nov 28, 2017
2af9453
Modify CollisionFreeOutcome to take Contact references as inputs as p…
evil-sherdil Nov 28, 2017
4ec21f8
Move include of sstream into .cpp file instead of header.
evil-sherdil Nov 28, 2017
4e2e20f
Made tests take advantage of programatic acess to data. Required addi…
evil-sherdil Nov 28, 2017
b8e0010
Made getter methods for Contact vectors const because they can be.
evil-sherdil Nov 28, 2017
816e86e
Address nits from @jslee02.
evil-sherdil Nov 30, 2017
4174efc
Two small nits I missed in the last commit.
evil-sherdil Nov 30, 2017
511555a
Aaaaaand, one more!
evil-sherdil Nov 30, 2017
b3da15d
Implemented createOutcome functionality in Testable base class.
evil-sherdil Dec 1, 2017
e061d63
Use auto collisionOutcome as per request of @brianhou.
evil-sherdil Dec 1, 2017
e1ed415
Merge branch 'master' into sniyaz/feature/testableConstraintOutput
evil-sherdil Dec 5, 2017
6c2dbec
Moved dynamic cast for outcome in CollisionFree.
evil-sherdil Dec 5, 2017
d3ada66
Added method to clear CollisionFreeOutcome. Use this method in Collis…
evil-sherdil Dec 5, 2017
7b10b67
Fixed directory placement of outcome classes. Renamed DummyOutcome --…
evil-sherdil Dec 5, 2017
0868db7
Added simple functionality to DefaultOutcome.
evil-sherdil Dec 5, 2017
cbc1b34
Responded to most recent review comments by making every Testable der…
evil-sherdil Dec 6, 2017
7a3b762
Run make format.
evil-sherdil Dec 6, 2017
079b2f3
[WIP] Refactor castic logic into helper, and use this in CollisionFre…
evil-sherdil Dec 6, 2017
e990862
[WIP] Replace redundant casting login in different Testables with hel…
evil-sherdil Dec 6, 2017
ce4160d
[WIP] Mop up some extra casts that were missed prior.
evil-sherdil Dec 6, 2017
4768cda
Added documentation.
evil-sherdil Dec 6, 2017
43c8f92
Make CollisionFree a friend class of CollisionFreeOutcome, use Eigen …
evil-sherdil Dec 6, 2017
e5e5d5b
Modify FrameTestable to "pass through" outcome object to mPoseConstra…
evil-sherdil Dec 6, 2017
354d3d5
Rename DefaultOutcome ---> DefaultTestableOutcome. Final clean up as …
evil-sherdil Dec 6, 2017
18b2dda
Merge branch 'master' into sniyaz/feature/testableConstraintOutput
brianhou Dec 7, 2017
cd9d522
Merge branch 'master' into sniyaz/feature/testableConstraintOutput
brianhou Dec 7, 2017
2c67a67
Merge branch 'master' into sniyaz/feature/testableConstraintOutput
brianhou Dec 8, 2017
0f6731b
Address @mkoval's comments.
brianhou Dec 11, 2017
d1b2040
Merge branch 'master' into sniyaz/feature/testableConstraintOutput
jslee02 Dec 12, 2017
ab1556f
Merge branch 'master' into sniyaz/feature/testableConstraintOutput
jslee02 Dec 15, 2017
b70af0a
Update nits: comment and renamed dynamic_cast_if_present to dynamic_c…
evil-sherdil Jan 5, 2018
9208f04
Undo the use of the Eigen allocator in CollisionFreeOutcome.
evil-sherdil Jan 5, 2018
12647a3
Update CHANGELOG.md
brianhou Jan 6, 2018
2fae405
Merge branch 'master' into sniyaz/feature/testableConstraintOutput
brianhou Jan 6, 2018
1357778
Merge branch 'master' into sniyaz/feature/testableConstraintOutput
jslee02 Jan 6, 2018
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
3 changes: 2 additions & 1 deletion include/aikido/constraint/CartesianProductTestable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ class CartesianProductTestable : public Testable
statespace::StateSpacePtr getStateSpace() const override;

bool isSatisfied(
const aikido::statespace::StateSpace::State* _state) const override;
const aikido::statespace::StateSpace::State* _state,
TestableOutcome* _outcome = nullptr) const override;

private:
std::shared_ptr<statespace::CartesianProduct> mStateSpace;
Expand Down
4 changes: 3 additions & 1 deletion include/aikido/constraint/CollisionFree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <dart/collision/CollisionOption.hpp>
#include "../statespace/dart/MetaSkeletonStateSpace.hpp"
#include "Testable.hpp"
#include "outcome/CollisionFreeOutcome.hpp"

namespace aikido {
namespace constraint {
Expand Down Expand Up @@ -41,7 +42,8 @@ class CollisionFree : public Testable

// Documentation inherited.
bool isSatisfied(
const aikido::statespace::StateSpace::State* _state) const override;
const aikido::statespace::StateSpace::State* _state,
TestableOutcome* _outcome = nullptr) const override;

/// Checks collision between group1 and group2.
/// \param group1 First collision group.
Expand Down
4 changes: 3 additions & 1 deletion include/aikido/constraint/FrameTestable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ class FrameTestable : public Testable
/// \param _state a MetaskeletonState to set the configuration of this
/// constraint's metaskeketon. This state's StateSpace should match
/// StateSpace returend by getStateSpace().
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document the TestableOutcome argument. I suggest making it simply return whatever TestableOutcome is returned by the _poseConstraint passed to this class' constructor.

bool isSatisfied(const statespace::StateSpace::State* _state) const override;
bool isSatisfied(
const statespace::StateSpace::State* _state,
TestableOutcome* _outcome = nullptr) const override;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Our convention is not to use a leading underscore for function parameter names. Please change _outcome to outcome for this function and other functions.


// Documentation inhereted
std::shared_ptr<statespace::StateSpace> getStateSpace() const override;
Expand Down
4 changes: 3 additions & 1 deletion include/aikido/constraint/Satisfied.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ class Satisfied : public constraint::Differentiable,
/// Returns \c true.
///
/// \param state a state in \c getStateSpace()
bool isSatisfied(const statespace::StateSpace::State* state) const override;
bool isSatisfied(
const statespace::StateSpace::State* state,
TestableOutcome* _outcome = nullptr) const override;

/// Sets \c _out to \c _s.
///
Expand Down
4 changes: 3 additions & 1 deletion include/aikido/constraint/TSR.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ class TSR : public Sampleable,
std::unique_ptr<SampleGenerator> createSampleGenerator() const override;

// Documentation inherited.
bool isSatisfied(const statespace::StateSpace::State* _s) const override;
bool isSatisfied(
const statespace::StateSpace::State* _s,
TestableOutcome* _outcome = nullptr) const override;

/// Throws an invalid_argument exception if this TSR is invalid.
/// For a TSR to be valid, mBw(i, 0) <= mBw(i, 1).
Expand Down
4 changes: 3 additions & 1 deletion include/aikido/constraint/Testable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <memory>
#include "../statespace/StateSpace.hpp"
#include "outcome/TestableOutcome.hpp"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We don't need to include this header in favor of the forward declaration as

namespace aikido {
namespace constraint {

class TestableOutcome;

/// Constraint which can be tested.
class Testable
{
   ...


namespace aikido {
namespace constraint {
Expand All @@ -15,7 +16,8 @@ class Testable

/// Returns true if state satisfies this constraint.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document the TestableOutcome parameter. Most importantly: (1) what type it must be and (2) what happens if it is not specified. 😉

virtual bool isSatisfied(
const statespace::StateSpace::State* _state) const = 0;
const statespace::StateSpace::State* _state,
TestableOutcome* _outcome = nullptr) const = 0;

/// Returns StateSpace in which this constraint operates.
virtual statespace::StateSpacePtr getStateSpace() const = 0;
Expand Down
3 changes: 2 additions & 1 deletion include/aikido/constraint/TestableIntersection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class TestableIntersection : public Testable

// Documentation inherited.
bool isSatisfied(
const aikido::statespace::StateSpace::State* state) const override;
const aikido::statespace::StateSpace::State* state,
TestableOutcome* _outcome = nullptr) const override;

// Documentation inherited.
statespace::StateSpacePtr getStateSpace() const override;
Expand Down
27 changes: 27 additions & 0 deletions include/aikido/constraint/outcome/CollisionFreeOutcome.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef AIKIDO_CONSTRAINT_COLLISIONFREEOUTCOME_HPP_
#define AIKIDO_CONSTRAINT_COLLISIONFREEOUTCOME_HPP_

#include <sstream>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: It seems we need to include <string> rather than <sstream>.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you elaborate on this a bit? If is not included, then it looks like the string building in toString won't work (since a string stream is used there, and then converted to a string object).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sstream is not exposed in this header file but used in the source file. So I suggest we include <string> as std::string is explicitly exposed in this header and include <sstream> in the source file where it's actually used.

The motivation behind this is that this way prevents unnecessarily including <sstream> by including CollisionFreeOutcome.hpp.

#include <vector>
#include "TestableOutcome.hpp"

namespace aikido {
namespace constraint {

class CollisionFreeOutcome : public TestableOutcome
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a simple docstring for this class like saying this class is a testable outcome for CollisionFree class?

{
public:
bool isSatisfied() const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Need override specifier.

std::string toString() const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Need override specifier.

void markCollisionBodyNode(const std::string& bodyNodeName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call this markPairwiseCollisionBodyNode?

void markSelfCollisionBodyNode(const std::string& bodyNodeName);

private:
std::vector<std::string> mCollisionBodyNodes;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and then call this mPairwiseCollisionBodyNodes.

std::vector<std::string> mSelfCollisionBodyNodes;
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have docstring for this class and its members?


} // namespace constraint
} // namespace aikido

#endif // ifndef AIKIDO_CONSTRAINT_COLLISIONFREEOUTCOME_HPP_
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: #endif // AIKIDO_CONSTRAINT_COLLISIONFREEOUTCOME_HPP_

19 changes: 19 additions & 0 deletions include/aikido/constraint/outcome/TestableOutcome.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef AIKIDO_CONSTRAINT_TESTABLEOUTCOME_HPP_
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe our convention is that we use a subdirectory when the class is in a nested namespace. The only exception (off the top of my head) is putting implementations of template classes under detail subdirectory. So I think TestableOutcome.hpp and CollisionFreeOutcome.hpp should be in just aikido/constraint (not aikido/constraint/outcome).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. My main reasoning here was that all of the things in the main directory seem to be constraints, and these new files aren't constraints- they're supposed to correspond to the outputs of constraints.

If nobody else has strong feelings either way, I'll move the files into the main constraint directory before merging.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually suggest putting this class definition directly in Testable.hpp. The TestableOutcome class is conceptually part of the Testable interface's public API.

If you think this would clutter that file too much, then moving it up to aikido/constraint makes sense to me. I agree with @jslee02 that putting this in its own subdirectory is inconsistent with our namespace convention.

#define AIKIDO_CONSTRAINT_TESTABLEOUTCOME_HPP_

#include <string>

namespace aikido {
namespace constraint {

class TestableOutcome
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add docstring for this class?

{
public:
virtual bool isSatisfied() const = 0;
virtual std::string toString() const = 0;
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have docstring for this class and its members?


} // namespace constraint
} // namespace aikido

#endif // ifndef AIKIDO_CONSTRAINT_TESTABLEOUTCOME_HPP_
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: #endif // AIKIDO_CONSTRAINT_TESTABLEOUTCOME_HPP_ as @brianhou mentioned.

4 changes: 3 additions & 1 deletion include/aikido/constraint/uniform/RnBoxConstraint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ class RBoxConstraint : public constraint::Differentiable,
std::vector<constraint::ConstraintType> getConstraintTypes() const override;

// Documentation inherited.
bool isSatisfied(const statespace::StateSpace::State* state) const override;
bool isSatisfied(
const statespace::StateSpace::State* state,
TestableOutcome* _outcome = nullptr) const override;

// Documentation inherited.
bool project(
Expand Down
4 changes: 3 additions & 1 deletion include/aikido/constraint/uniform/SE2BoxConstraint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class SE2BoxConstraint : public constraint::Projectable,
statespace::StateSpacePtr getStateSpace() const override;

// Documentation inherited.
bool isSatisfied(const statespace::StateSpace::State* state) const override;
bool isSatisfied(
const statespace::StateSpace::State* state,
TestableOutcome* _outcome = nullptr) const override;

// Documentation inherited.
bool project(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ std::vector<ConstraintType> RBoxConstraint<N>::getConstraintTypes() const
//==============================================================================
template <int N>
bool RBoxConstraint<N>::isSatisfied(
const statespace::StateSpace::State* state) const
const statespace::StateSpace::State* state, TestableOutcome* _outcome) const
{
const auto value = mSpace->getValue(
static_cast<const typename statespace::R<N>::State*>(state));
Expand Down
1 change: 1 addition & 0 deletions src/constraint/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
set(sources
outcome/CollisionFreeOutcome.cpp
uniform/RnBoxConstraint.cpp
uniform/RnConstantSampler.cpp
uniform/SO2UniformSampler.cpp
Expand Down
3 changes: 2 additions & 1 deletion src/constraint/CartesianProductTestable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ statespace::StateSpacePtr CartesianProductTestable::getStateSpace() const

//==============================================================================
bool CartesianProductTestable::isSatisfied(
const aikido::statespace::StateSpace::State* _state) const
const aikido::statespace::StateSpace::State* _state,
TestableOutcome* _outcome) const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A general way to suppress warnings for unused parameter is simply commenting out the parameter name as

 bool CartesianProductTestable::isSatisfied(
    const aikido::statespace::StateSpace::State* _state,
    TestableOutcome* /*_outcome*/) const

This is an answer to TODOs.1.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! 😄 This is a super handy thing to know.

{
const auto state
= static_cast<const statespace::CartesianProduct::State*>(_state);
Expand Down
26 changes: 25 additions & 1 deletion src/constraint/CollisionFree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ statespace::StateSpacePtr CollisionFree::getStateSpace() const

//==============================================================================
bool CollisionFree::isSatisfied(
const aikido::statespace::StateSpace::State* _state) const
const aikido::statespace::StateSpace::State* _state,
TestableOutcome* _outcome) const
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should clear the CollisionFreeOutcome, just in case the user passes the same instance of the outcome object to multiple function calls. This would actually be a pretty common use-case, since motion planners routinely re-use objects to avoid needlessly reallocating memory.

auto skelStatePtr = static_cast<const aikido::statespace::dart::
MetaSkeletonStateSpace::State*>(_state);
Expand All @@ -42,16 +43,39 @@ bool CollisionFree::isSatisfied(
groups.second.get(),
mCollisionOptions,
&collisionResult);

if (collision)
{
if (_outcome != nullptr)
{
auto collisionOutcome = static_cast<CollisionFreeOutcome*>(_outcome);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not guaranteed if _outcome is the type of CollisionFreeOutcome*. I think we should do one of the follows:
(1) use assertion (in debug mode) and dynamic_cast to check if _outcome is the right type. The downside would be that we still have problem in release mode
(2) run the routine only when it succeded to cast to the right type using dynamic_cast (warnings if the type is not the right one). The downside would be the overhaed of using dynamic_cast.
(3) throw exception when the type is not right. The downside would be that it has to use dynamic_cast anyway.

I'm not sure what would be the preferred way here. @brianhou , @mkoval, @gilwoolee thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the only difference between (2) and (3) whether we silently fail or raise an exception when the TestableOutcome is the wrong type? In that case, I think I'd prefer (3) over (2) to make sure we know that we've made a mistake.

My (limited) understanding is that we won't be passing a non-null TestableOutcome that often, so I'm also not as concerned about the overhead of using a dynamic_cast in release mode. Perhaps we can use (3) now and if it becomes performance-critical we can re-evaluate and perhaps switch to (1).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this logic (assuming that @brianhou's reasoning about (2) and (3) is correct). I'm going to with (3) right now, and we can change if people have strong feelings towards either approach.

auto collidingBodies = collisionResult.getCollidingBodyNodes();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: const auto& to avoid the unnecessary copy.

for (const auto& elem : collidingBodies)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this should iterate over CollisionResult::getContacts() instead. That will allow us to specify which pairs of bodies are in collision, rather than squashing that information into a list of bodies that are in collision.

This isn't a problem now because our default CollisionOption only detects a maximum of one contact between two bodies, but we may as well support multiple contacts on the off-chance that becomes helpful.

{
collisionOutcome->markCollisionBodyNode(elem->getName());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: If you make CollisionFreeOutcome a friend class, then this could be reduced to:

collisionFreeOutcome->mContacts = collisionResult.getContacts();

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all the awesome feedback! 😄 I had a question about this one- when using Eigen::aligned_allocator (as mentioned in a previous comment), wouldn't this be not possible? The two vectors appear to use different allocators.

Copy link
Member

@mkoval mkoval Dec 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect this is actually a bug in DART! 😬 @mxgrey @jslee02

In any case, you can still do the assignment with a bit more boilerplate:

const auto& contacts = collisionResult.getContacts();
collisionFreeOutcome->mContacts.assign(std::begin(contacts), std::end(contacts));

}
return false;
}
}

for (auto group : mGroupsToSelfCheck)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This is irrelevant to this PR, but let's avoid unnecessary copy here by changing this line to for (const auto& group : mGroupsToSelfCheck).

Also for (auto groups : mGroupsToPairwiseCheck) should be for (const auto& groups : mGroupsToPairwiseCheck)

{
collision = mCollisionDetector->collide(
group.get(), mCollisionOptions, &collisionResult);
if (collision)
{
if (_outcome != nullptr)
{
auto collisionOutcome = static_cast<CollisionFreeOutcome*>(_outcome);
auto collidingBodies = collisionResult.getCollidingBodyNodes();
for (const auto& elem : collidingBodies)
{
collisionOutcome->markSelfCollisionBodyNode(elem->getName());
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: If you make CollisionFreeOutcome a friend class, then this could be reduced to:

collisionFreeOutcome->mSelfContacts = collisionResult.getContacts();

return false;
}
}
return true;
}
Expand Down
3 changes: 2 additions & 1 deletion src/constraint/FrameTestable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ FrameTestable::FrameTestable(

//==============================================================================
bool FrameTestable::isSatisfied(
const statespace::StateSpace::State* _state) const
const statespace::StateSpace::State* _state,
TestableOutcome* _outcome) const
{
// Set the state
auto state
Expand Down
3 changes: 2 additions & 1 deletion src/constraint/Satisfied.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ std::vector<constraint::ConstraintType> Satisfied::getConstraintTypes() const

//==============================================================================
bool Satisfied::isSatisfied(
const statespace::StateSpace::State* /*state*/) const
const statespace::StateSpace::State* /*state*/,
TestableOutcome* /*_outcome*/) const
{
return true;
}
Expand Down
3 changes: 2 additions & 1 deletion src/constraint/TSR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ std::unique_ptr<SampleGenerator> TSR::createSampleGenerator() const
}

//==============================================================================
bool TSR::isSatisfied(const statespace::StateSpace::State* _s) const
bool TSR::isSatisfied(
const statespace::StateSpace::State* _s, TestableOutcome* _outcome) const
{
Eigen::VectorXd dist;
getValue(_s, dist);
Expand Down
3 changes: 2 additions & 1 deletion src/constraint/TestableIntersection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ TestableIntersection::TestableIntersection(

//==============================================================================
bool TestableIntersection::isSatisfied(
const aikido::statespace::StateSpace::State* _state) const
const aikido::statespace::StateSpace::State* _state,
TestableOutcome* _outcome) const
{
for (auto c : mConstraints)
{
Expand Down
51 changes: 51 additions & 0 deletions src/constraint/outcome/CollisionFreeOutcome.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include <aikido/constraint/outcome/CollisionFreeOutcome.hpp>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nit: In a source file, we include the associated header very first then others in order of STL headers, 3rd party library headers, and AIKIDO headers.


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to include <sstream> here instead.

namespace aikido {
namespace constraint {

//==============================================================================
bool CollisionFreeOutcome::isSatisfied() const
{
if (mCollisionBodyNodes.size() > 0 || mSelfCollisionBodyNodes.size() > 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: empty() is the preferred way to check the emptiness of a container over using size().

{
return false;
}

return true;
}

//==============================================================================
std::string CollisionFreeOutcome::toString() const
{
std::stringstream ss;
ss << "ALL COLLISIONS: " << std::endl;

for (auto collBodyNodeName : mCollisionBodyNodes)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: const auto&

{
ss << "[COLLISION]: " << collBodyNodeName << std::endl;
}

for (auto selfCollBodyNodeName : mSelfCollisionBodyNodes)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: const auto&

{
ss << "[SELF COLLISION]: " << selfCollBodyNodeName << std::endl;
}

return std::move(ss.str());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we don't need to use std::move() for returning local variable in favor of RVO.

}

//==============================================================================
void CollisionFreeOutcome::markCollisionBodyNode(
const std::string& bodyNodeName)
{
mCollisionBodyNodes.push_back(bodyNodeName);
}

//==============================================================================
void CollisionFreeOutcome::markSelfCollisionBodyNode(
const std::string& bodyNodeName)
{
mSelfCollisionBodyNodes.push_back(bodyNodeName);
}

} // namespace constraint
} // namespace aikido
4 changes: 2 additions & 2 deletions src/constraint/uniform/SE2BoxConstraint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ statespace::StateSpacePtr SE2BoxConstraint::getStateSpace() const

//==============================================================================
bool SE2BoxConstraint::isSatisfied(
const statespace::StateSpace::State* state) const
const statespace::StateSpace::State* state, TestableOutcome* _outcome) const
{
Eigen::VectorXd tangent;
mSpace->logMap(static_cast<const statespace::SE2::State*>(state), tangent);
Expand Down Expand Up @@ -207,4 +207,4 @@ Eigen::Vector2d SE2BoxConstraint::getUpperLimits() const
}

} // namespace statespace
} // namespace aikido
} // namespace aikido
8 changes: 6 additions & 2 deletions tests/constraint/MockConstraints.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ class PassingConstraint : public aikido::constraint::Testable
}

bool isSatisfied(
const aikido::statespace::StateSpace::State* /*state*/) const override
const aikido::statespace::StateSpace::State* /*state*/,
aikido::constraint::TestableOutcome* = nullptr /*_outcome*/)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: aikido::constraint::TestableOutcome* /*_outcome*/ = nullptr looks more reasonable to me.

const override
{
return true;
}
Expand All @@ -38,7 +40,9 @@ class FailingConstraint : public aikido::constraint::Testable
}

bool isSatisfied(
const aikido::statespace::StateSpace::State* /*state*/) const override
const aikido::statespace::StateSpace::State* /*state*/,
aikido::constraint::TestableOutcome* = nullptr /*_outcome*/)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: aikido::constraint::TestableOutcome* /*_outcome*/ = nullptr looks more reasonable to me.

const override
{
return false;
}
Expand Down
Loading