-
Notifications
You must be signed in to change notification settings - Fork 92
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
Improve performance of bodies::setPose() #126
Improve performance of bodies::setPose() #126
Conversation
As was suggested in #125, I didn't create a performance test that would be a part of the package, because the rules on how to write them in a non-flaky way are unclear. Anyways, if anybody wanted to replicate my experiments, here's the test code:
|
Things to do on a Saturday night. 😎 The |
You're right, the quarantine has some positive effects for open source, I'd say. I was also thinking about adding a method like the one you suggest, maybe rather with pointer arguments to allow setting just some of them. Also Another approach I can think of is adding an optional parameter to Yet another approach would be to add some "factory-like" object, e.g. |
You mixed up API and ABI: a new optional parameter breaks ABI, not API. |
Okay, adding new setters sounds reasonable. I'm just thinking whether to use |
Either is fine.
Consistent naming is important. I prefer |
8873450
to
44d28e4
Compare
I added the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me and does not break API/ABI.
The only unresolved question is whether we want to merge 4f5a7be in melodic-devel still.
Once this is decided (tomorrows meeting), this can be merged as appropriate.
I added the isometry asserts. Once we agree on the correct approach, I'll update the moveit PR, too. Here I added a "no-op" message as the first test in the assert so that when code fails on the assert, the user will see something more friendly than just a bunch of mathematical computations (C++ prints out the whole definition of the assert that failed). |
The error message looks exactly like this: https://travis-ci.org/github/ros-planning/geometric_shapes/jobs/667849514#L911 :-D Any idea why the test succeeded on melodic and failed on kinetic? |
51af3e5
to
60aba15
Compare
Ah, kinetic build was choosing the integral version of I also made the assert macro a bit more verbose so that the user can see not only the failed condition, but also the value of the transformation matrix and its computed determinant. This comes at the cost of uglier macro, but provides better user experience. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I very much like the current approach and clean implementation.
Ready for merge in my opinion. I'm still happy to merge this in melodic-devel
, alternatively we have to split off a noetic-devel
branch already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally looks good. Some minor remarks though.
@rhaschke This should be ready to merge. |
…essary dynamic memory allocation.
35a76c7
to
e170bcf
Compare
There was a forgotten non-isometry in test_bounding_cylinder. It did not trigger locally for me beacause this branch was not up-to-date with melodic-devel. I rebased and now let's hope the tests will pass. |
include/geometric_shapes/bodies.h
Outdated
#ifdef NDEBUG | ||
#define ASSERT_ISOMETRY(transform) assert(true); | ||
#else | ||
#define ASSERT_ISOMETRY(transform) \ | ||
{ \ | ||
bool isIsometry = (transform).matrix()(3, 0) == 0 && (transform).matrix()(3, 1) == 0 && \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rhaschke Are you sure this check is done by design? Wouldn't that only be the case in the "efficient storage" which only stores a 3x4 matrix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True. Will revert.
test/test_basics.cpp
Outdated
|
||
t.linear() = t.linear() * Eigen::DiagonalMatrix<double, 3, 3>(1.0, 2.0, 3.0); | ||
ASSERT_DEATH(ASSERT_ISOMETRY(t), "Invalid isometry transform"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the test do at least something in release mode? I.e. test that calling the assert on invalid transform would not actually do anything?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I can change this.
Do you want to keep the different commits of this PR or can I squash-merge it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the last two or three commits do not carry any useful information, but I think the previous ones are nicely "decoupled" and explain why each change was made. I'd vouch for keeping these.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem. In this case, I ask you to cleanup the history along the following line:
pick 074502d Normalize the direction vector passed to Body::intersectsRay() (#115)
pick e2f4850 Improved performance of Body::setPose() by calling .linear() instead of .rotation().
pick 8dfe31c Improved performance of ConvexMesh::setPose() by getting rid of unnecessary dynamic memory allocation.
pick 13d662e Fixed test_bounding_box.cpp wrong usage of AngleAxis with denormalized axes.
squash e170bcf Fixed a non-isometry in test_bounding_cylinder
pick 5381162 Added dirty versions of setScale/setPadding/setPose/setDimensions and made updateInternalData public.
pick 9c678de Added asserts that check bodies::Body::pose_ is an actual isometry before calling .linear() on it.
fixup 8555637 Fixed ASSERT_ISOMETRY, made setDimensionsDirty() inline.
fixup 721e0b1 Cleanup of ASSERT_ISOMETRY
fixup f3a3af5 fixup! Cleanup of ASSERT_ISOMETRY
Obviously, the commit 8555637 Fixed ASSERT_ISOMETRY, made setDimensionsDirty() inline.
needs to be split up onto two previous commits.
Fixed a non-isometry in test_bounding_cylinder
… made updateInternalData public. This allows improving performance of ConvexMesh::setPose() by optimizing construction of the helper Box class.
…fore calling .linear() on it.
f3a3af5
to
505671f
Compare
I cleaned up the commit history. |
Performance of bodies::setPose() was improved by calling .linear() instead of .rotation().
For isometries, these should result to the same code, but this optimization is not in any released version of Eigen so far (3.3.7).
I also had to fix test_bounding_box.cpp test, as I found there a few usages of AngleAxis to which a denormalized axis was passed, which is illegal. And the fixes in this PR broke one of the wrong tests.
I also did additional speedups in ConvexMesh::setPose().
First, there was an unncessary dynamic memory allocation, which was not optimized out by the compiler (removing the allocation speeded up the pref. test by ~25%).
Second, the construction of the helper bounding_box_ object led to calling Box::updateInternalData() 4 times in succession. So I fixed that by accessing the protected members of Box and making ConvexMesh its friend class. If this approach is not desirable, I extracted it to a single commit which can be reverted.
For the measured performance improvement, see #125 (comment).