-
Notifications
You must be signed in to change notification settings - Fork 30
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
Addes TSR visualizer to aikido/rviz. #136
Conversation
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.
🎉 Thanks for adding this. This is very useful.
I added a few minor comments, but am happy to merge this once they are addressed.
src/rviz/InteractiveMarkerViewer.cpp
Outdated
|
||
for(int i = 0; i < nSamples && sampler->canSample(); ++i) | ||
{ | ||
sampler->sample(state); |
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.
Check the return value of sample
. In principle it should not return false
if canSample()
returned true
, so an assertion would be fine.
src/rviz/InteractiveMarkerViewer.cpp
Outdated
sampler->sample(state); | ||
|
||
std::stringstream sstm; | ||
sstm << "tsr" << i; |
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.
Suggestion: Make the base name a std::string
parameter. I suggest making it default to something that includes the &tsr
(or, even better, the memory address of the return value) to avoid name collisions.
src/rviz/InteractiveMarkerViewer.cpp
Outdated
auto tsrFrame = std::make_shared<SimpleFrame>( | ||
Frame::World(), sstm.str(), state.getIsometry()); | ||
mSimpleFrames.push_back(tsrFrame); | ||
this->addFrame(tsrFrame.get()); |
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.
Nit: We don't typically explicitly specify this->
unless there is a name conflict.
Also, I'd prefer to aggregate all of the FrameMarkerPtr
s returned by addFrame
into an RAII object (perhaps TSRMarker
😉) that we return from this function. That would also make clearTSRs
and the mSimpleFrames
member variable superfluous, since they could be replaced by the RAII object.
@@ -32,6 +33,10 @@ class InteractiveMarkerViewer { | |||
SkeletonMarkerPtr CreateSkeletonMarker( | |||
dart::dynamics::SkeletonPtr const &skeleton); | |||
|
|||
/// Visualizes tsr with at most n samples | |||
void visualizeTSR(const aikido::constraint::TSR& _tsr, int nSamples = 10); |
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.
Please add a full docstring.
…nto rviz/visualizeTSR
…cs/aikido into rviz/visualizeTSR
src/rviz/InteractiveMarkerViewer.cpp
Outdated
@@ -49,6 +50,42 @@ FrameMarkerPtr InteractiveMarkerViewer::addFrame( | |||
return marker; | |||
} | |||
|
|||
TSRMarkerPtr InteractiveMarkerViewer::visualizeTSR( |
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.
Rename this to addTSRMarker
to be consistent with addFrameMarker
.
src/rviz/InteractiveMarkerViewer.cpp
Outdated
TSRMarkerPtr InteractiveMarkerViewer::visualizeTSR( | ||
aikido::constraint::TSR const &_tsr, | ||
int nSamples, | ||
std::string basename) |
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.
Take basename
by const std::string&
.
src/rviz/InteractiveMarkerViewer.cpp
Outdated
if (basename == "") | ||
{ | ||
std::ostringstream ost; | ||
ost << &tsrMarker; |
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.
tsrMarker
is a smart_ptr
, so this should be tsrMarker.get()
to get the memory address of the heap memory. It's possible that repeated calls of this function in a loop could allocate tsrMarker
itself at the same memory address on the stack.
src/rviz/InteractiveMarkerViewer.cpp
Outdated
auto state = _tsr.getSE3()->createState(); | ||
auto tsrMarker = std::make_shared<TSRMarker>(); | ||
|
||
if (basename == "") |
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.
Nit: basename.empty()
.
src/rviz/InteractiveMarkerViewer.cpp
Outdated
assert(sampler->sample(state)); | ||
|
||
std::stringstream ss; | ||
ss << "Marker[" << basename << "].frame[" << i << "]"; |
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.
Nit: Marker
-> TSRMarker
to avoid collisions with other markers we add in the future.
include/aikido/rviz/TSRMarker.hpp
Outdated
TSRMarker(); | ||
~TSRMarker(){}; | ||
|
||
void addFrameMarker(FrameMarkerPtr const &marker); |
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 don't think this should be part of the public API. The simplest option would be to modify TSRMarker
's constructor to directly accept the std::set<FrameMarkerPtr>
.
include/aikido/rviz/TSRMarker.hpp
Outdated
class TSRMarker { | ||
public: | ||
TSRMarker(); | ||
~TSRMarker(){}; |
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.
Nit: Use ~TSRMarker = default
instead.
include/aikido/rviz/TSRMarker.hpp
Outdated
namespace aikido { | ||
namespace rviz { | ||
|
||
class TSRMarker { |
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.
Nit: Either mark this as final
or mark the destructor as virtual
.
include/aikido/rviz/TSRMarker.hpp
Outdated
void addFrameMarker(FrameMarkerPtr const &marker); | ||
|
||
private: | ||
std::set<FrameMarkerPtr> mFrameMarkers; |
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.
Nit: Why does this need to be an std::set
? I'd prefer an std::vector
here, since linear memory is a lot simpler than a red-black tree, if we don't require uniqueness.
@mkoval I think I addressed all of your comments. Please take a look. Thanks for the help! |
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.
LGTM. I left one minor comment, but feel free to ignore.
src/rviz/InteractiveMarkerViewer.cpp
Outdated
auto tsrFrame = std::make_shared<SimpleFrame>( | ||
Frame::World(), ss.str(), state.getIsometry()); | ||
auto frameMarker = addFrame(tsrFrame.get()); | ||
tsrFrames.emplace_back(tsrFrame); |
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.
Nit: Could we use unique_ptr
instead of shared_ptr
here?
@mkoval Would you mind taking a last look before I merge this? It just changes |
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! @gilwoolee feel free to merge.
@@ -17,6 +17,10 @@ class SkeletonMarker; | |||
typedef std::shared_ptr<SkeletonMarker> SkeletonMarkerPtr; | |||
typedef std::shared_ptr<SkeletonMarker const> SkeletonMarkerConstPtr; | |||
|
|||
class TSRMarker; | |||
typedef std::shared_ptr<TSRMarker> TSRMarkerPtr; | |||
typedef std::shared_ptr<TSRMarker const> TSRMarkerConstPtr; |
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.
Nit: Prefer using
aliases to typedef
s.
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.
Please place const
before type. See above.
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.
Commented some style related nitpicks.
namespace aikido { | ||
namespace rviz { | ||
|
||
TSRMarker::TSRMarker(std::vector<std::unique_ptr<SimpleFrame>> tsrFrames) |
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.
We could use rvalue reference (std::vector<std::unique_ptr<SimpleFrame>>&& tsrFrames
) here to prevent unnecessary copy.
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.
This already doesn't make any copies if the caller uses std::move
, e.g.:
// Caller std::move's from local variable to argument:
std::vector<std::unique_ptr<SimpleFrame>> frames = /* ... */;
auto marker = TSRMarker{std::move(frames)};
// Constructor std::moves from argument to member variable:
TSRMarker::TSRMarker(std::vector<std::unique_ptr<SimpleFrame>> frames)
: markers{std::move(frames)} {}
Note that std::vector<std::unique_ptr<...>>
is not copyable, so we already must not be introducing an extra copy. 😉
My general understanding is that rvalue references are only useful for: (1) move constructors and (2) perfect forwarding in templates due to reference collapsing.
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.
This already doesn't make any copies if the caller uses
std::move
That is true, but the explicit rvalue argument could prevent passing lvalue by accident (if I'm missing something here). For example:
class TSRMarker
{
public:
TSRMarker(std::vector<std::unique_ptr<SimpleFrame>>&& tsrFrames);
// ...
};
std::vector<std::unique_ptr<SimpleFrame>> frames = /* ... */;
auto marker1 = TSRMarker{frames}; // error
auto marker2 = TSRMarker{std::move(frames)}; // okay
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.
Note that std::vector<std::unique_ptr<...>> is not copyable, so we already must not be introducing an extra copy.
Hm, this is what I missed. It still prevents passing lvalue even without making it rvalue reference but in a different way (we get different error messages).
I still prefer to make the argument explicitly rvalue reference because we always expect to pass rvalue here. However, I am not strongly against leaving it as it is since it works as we intend anyway.
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 disagree! 😬 I prefer to leave copy versus move up to the caller (i.e. leave the code as it is).
I don't feel particularly strongly either way, so let's leave it up to @gilwoolee to decide. 😄
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 don't feel particularly strongly either way, so let's leave it up to @gilwoolee to decide.
👍
My only concern is that the caller is not able to pass lvalue anyway (whether or not the argument is rvalue reference because copy assignment of std::unique_ptr
is not defined), but explicit rvalue reference argument could give us hint why the caller cannot pass lvalue.
Alright, let's pass the baton to @gilwoolee. 😈
/// \param basename Basename for markers | ||
/// \return TSRMarkerPtr contains sampled frames of TSR. | ||
TSRMarkerPtr addTSRMarker( | ||
aikido::constraint::TSR const &tsr, |
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 believe the convention is to place const
before type and space after &
as const aikido::constraint::TSR& tsr
.
/// \return TSRMarkerPtr contains sampled frames of TSR. | ||
TSRMarkerPtr addTSRMarker( | ||
aikido::constraint::TSR const &tsr, | ||
int nSamples = 10, const std::string &basename = ""); |
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.
Please put a space after & not not before. See above.
@@ -17,6 +17,10 @@ class SkeletonMarker; | |||
typedef std::shared_ptr<SkeletonMarker> SkeletonMarkerPtr; | |||
typedef std::shared_ptr<SkeletonMarker const> SkeletonMarkerConstPtr; | |||
|
|||
class TSRMarker; | |||
typedef std::shared_ptr<TSRMarker> TSRMarkerPtr; | |||
typedef std::shared_ptr<TSRMarker const> TSRMarkerConstPtr; |
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.
Please place const
before type. See above.
This change is![Reviewable](https://camo.githubusercontent.com/1541c4039185914e83657d3683ec25920c672c6c5c7ab4240ee7bff601adec0b/68747470733a2f2f72657669657761626c652e696f2f7265766965775f627574746f6e2e737667)