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

Make transformation framework pluggable #346

Merged

Conversation

greimela-si
Copy link
Contributor

This change allows developers to provide their own transformation library to be used instead of tf2.

Two transformer plugins are bundled with RViz:

  • A tf2 plugin which transforms using the tf2 library
  • A trivial identity plugin which always uses the identity as transformation

The tf2 plugin is used as default, which means users normally do not have to interact with the transformation plugins.

We also added a new transformation panel to change the transformation plugin at runtime.
This panel displays all transformation plugins available at startup, third party plugins are loaded using the pluginlib.

The documentation was extended accordingly to support developers creating their own transformation plugin.

@esteve esteve added the in review Waiting for review (Kanban column) label Aug 1, 2018
@greimela-si
Copy link
Contributor Author

CI:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@Martin-Idel-SI Martin-Idel-SI force-pushed the feature/use_pluginlib_for_frame_transformer branch from 6f6b2c2 to a312050 Compare August 7, 2018 11:51
@Martin-Idel-SI
Copy link
Contributor

CI after rebase:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@wjwwood wjwwood self-assigned this Aug 9, 2018
@wjwwood
Copy link
Member

wjwwood commented Aug 9, 2018

Sorry looks like I caused a merge conflict by merging other stuff. I got part of the way through the review, and I'll try to continue it soon.

@Martin-Idel-SI
Copy link
Contributor

No worries, we'll rebase.

@botteroa-si botteroa-si force-pushed the feature/use_pluginlib_for_frame_transformer branch from a312050 to f7447e2 Compare August 9, 2018 16:00
@botteroa-si
Copy link
Contributor

New CI after rebase:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

Copy link
Member

@wjwwood wjwwood left a comment

Choose a reason for hiding this comment

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

Ok, I finally got through the review, sorry it took so long, but this was a large change, I had to break it into three sessions.

So the code review looks pretty good to me, I have some style things I want to address, but I'll do that in a pull request probably tomorrow.

Unfortunately, my testing of the new UI elements revealed some strange behavior. I made a video of me clicking around on it (the most interesting issue is towards the end):

https://media.giphy.com/media/1hMhlfukXkMhsX2Thq/giphy.mp4

The issues I see in the video:

  • the save and reset buttons do not disable after saving sometimes
  • what does the reset button do?
  • after using the reset button I can sometimes check both boxes...

I also got a segmentation fault once but I wasn't running in gdb and I could not reproduce it, but I was doing stuff similar to what I was doing in the video, just clicking around.

I also got this log message when clicking around:

[ERROR] []: Failed to remove time jump callback

Which seems to be from the destruction of an rclcpp::Clock class and it's time jump callback, here:

https://github.com/ros2/rclcpp/blob/a55e320e6eb3364258360d216657bec38020e0b5/rclcpp/src/rclcpp/clock.cpp#L143

Which was added in this pull request:

ros2/rclcpp#543

/cc @sloretz in case you have any idea how our use of clock in this pr might cause that behavior.


I know you guys have been waiting to get this merged for a long time (sorry, my fault) but I think the UI issues need to be investigated before we merge this.

To make them available at runtime, use the cmake macro `register_rviz_ogre_media_exports` defined in `rviz_rendering`
For instance, if you want to register a folder `test_folder/scripts` which resides in your project's source folder, write
```
register_rviz_ogre_media_exports(DIRECTORIES "test_folder/scripts")
```
*Note:* If you want to export folder hierarchies, each folder needs to be exported separately. Folders within exported folders are not automatically available.

#### Writing a display which can only work with one transformation plugin

Some of the default displays (e.g. TF display or LaserScan display) can only work with tf2 as transformation framework.
Copy link
Member

Choose a reason for hiding this comment

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

Why can the LaserScan display only work with tf2?

Copy link
Contributor

Choose a reason for hiding this comment

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

The laser_geometry package used internally needs a tf2_buffer. Since it is not very easy to get around this (one would need to heavily rewrite some parts in laser_geometry), we decided that it's probably better to leave it out for now.

The class `rviz_default_plugins::transformation::TransformerGuard` helps you to handle these possibilities.

As explained in the relative section, every transformation plugin implements the base class `rviz_common::transformation::FrameTransformer`.
The `TransformerGuard` class is templated on the type of this implementation and will make sure that the display by which is owned will be disabled if the transformer currently in use is of a different type.
Copy link
Member

Choose a reason for hiding this comment

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

"... by which it is owned ..."?

The `TransformerGuard` class is templated on the type of this implementation and will make sure that the display by which is owned will be disabled if the transformer currently in use is of a different type.

When writing a display that is supposed to be working only with a specific transformation plugin, you can add a templated instance of `TransformerGuard` as a display member.
The constructor of this class takes two argument: a raw pointer to the display that owns it, and the name of the transformer it is supposed to work with (needed to correctly set the error status).
Copy link
Member

Choose a reason for hiding this comment

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

Can it work with more than one kind? Or can you only have one TransformerGuard per display?

Copy link
Contributor

Choose a reason for hiding this comment

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

No. Onle one TransformerGuard per display is supported.
Reason: The only reason for a display to require a special FrameTransformer would be if the FrameTransformer interface is not sufficient. I think there is likely only a single frame transformer plugin that fulfills this special requirement (at least that the display knows of).

If support for more allowed transformer plugins is really necessary it should be possible the extend TransformerGuard to support multiple template parameters for the supported plugins but still have only a single guard member in a display.

virtual ~TransformationLibraryConnector() = default;
};

using TransformationLibraryConnectorPtr = std::weak_ptr<TransformationLibraryConnector>;
Copy link
Member

Choose a reason for hiding this comment

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

Usually the analogy for Ptr is a raw pointer or unique_ptr (because it has almost no overhead compared to raw pointer), however weak_ptr does have overhead. I'd recommend using WeakPtr as the suffix here.

Copy link
Member

Choose a reason for hiding this comment

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

Or just use std::weak_ptr<TransformationLibraryConnector> everywhere.

Copy link
Contributor

Choose a reason for hiding this comment

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

We will use the ::WeakPtr convention.

{

/** @brief Base class for TransformerGuard, needed because Qt's moc and c++
* templates don't work nicely together. Not intended to be used directly.
Copy link
Member

Choose a reason for hiding this comment

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

Can you please elaborate on this point?

Copy link
Contributor

@anhosi anhosi Sep 6, 2018

Choose a reason for hiding this comment

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

Same reason as with rviz_common::RosTopicdisplay and rviz_common::_RosTopicDisplay: a QObject may not be a template class due to limitations imposed by the Qt moc.

} catch (const tf2::ExtrapolationException & exception) {
throw rviz_common::transformation::FrameTransformerException(exception.what());
} catch (const tf2::InvalidArgumentException & exception) {
throw rviz_common::transformation::FrameTransformerException(exception.what());
Copy link
Member

Choose a reason for hiding this comment

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

So much information is lost here... Maybe you should prefix the error message with the original name of the error.

@Martin-Idel-SI
Copy link
Contributor

Martin-Idel-SI commented Sep 6, 2018

Thank you for the feedback! I investigated the UI issues:

  • I removed the reset button. It doesn't really do much, especially since I doubt any user will ever need it.
  • We have still an issue where sometimes, changing the checkbox does not enable/disable the save button. As far as I can see, this is a bug in Qt: For an unknown reason, very rarely, the QtTreeWidget clicked signal is not sent or does not arrive, while the checkbox signal does.

There are two simple workarounds that I see, which would you prefer @wjwwood :

  • Don't disable the save button ever and make it a noop if the transformer hasn't changed
  • Disable the setValue method of the checkbox. This means that in the rare cases where previously the state of the checkboxes changed but the button was not disabled/enabled, nothing will happen. It'll be as if the user missed the target. Since at least on our systems this happens quite rarely (I usually clicked around for a couple of minutes to see this behaviour), I think hardly any user would ever even notice.

The latter would be a achieved by making setValue in grouped_checkbox_property.cpp a noop. Then we provide the functionality in a new method to be called by transformation_panel.cpp.

@greimela-si
Copy link
Contributor Author

I also got a segmentation fault once but I wasn't running in gdb and I could not reproduce it, but I was doing stuff similar to what I was doing in the video, just clicking around.

You are right, these issues have been introduced after ros2/rclcpp#543.

We managed to track the issue inside the rcl and opened an issue there: ros2/rcl#293.
Short version: The reallocation of freed memory resulted in undefined behavior.

@Martin-Idel-SI
Copy link
Contributor

Martin-Idel-SI commented Sep 6, 2018

CI:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@sloretz
Copy link
Contributor

sloretz commented Sep 6, 2018

I also got this log message when clicking around:

[ERROR] []: Failed to remove time jump callback
Which seems to be from the destruction of an rclcpp::Clock class and it's time jump callback, here:

https://github.com/ros2/rclcpp/blob/a55e320e6eb3364258360d216657bec38020e0b5/rclcpp/src/rclcpp/clock.cpp#L143

Which was added in this pull request:

ros2/rclcpp#543

Looking into this.

@wjwwood
Copy link
Member

wjwwood commented Sep 6, 2018

Thanks for the fast feedback.

There are two simple workarounds that I see, which would you prefer @wjwwood :

The second seems reasonable to me.

It looks like the Linux tests are taking a long time due to failing tests. My first instinct is to rebase this change, but I don't think much changed within rviz that might affect this pr.

I'll probably do that to keep the ball rolling.

botteroa-si and others added 5 commits September 6, 2018 14:43
- use "::WeakPtr" convention
- add missing visibility macro to TransformationManager
- retain information about tf exceptions when re-throwing
- fix documentation typo
- superfluous for small amount of checkboxes
- Code-Style: reorder functions in transformer panel
@wjwwood
Copy link
Member

wjwwood commented Sep 6, 2018

I pushed the rebase to the branch bsinno/feature/use_pluginlib_for_frame_transformer on this repository, and I'm going to test that, then force push to this pr if it works.

@wjwwood
Copy link
Member

wjwwood commented Sep 6, 2018

I'm just running on Linux right now: Build Status

@wjwwood wjwwood force-pushed the feature/use_pluginlib_for_frame_transformer branch from 3216dd5 to 356f60b Compare September 6, 2018 22:54
@wjwwood
Copy link
Member

wjwwood commented Sep 6, 2018

Ok that run looked good so I force pushed the rebase. I'm just checking on a few things and then I'll do CI on your branch (what this pr is actually testing).

Signed-off-by: William Woodall <william@osrfoundation.org>
Signed-off-by: William Woodall <william@osrfoundation.org>
Signed-off-by: William Woodall <william@osrfoundation.org>
Signed-off-by: William Woodall <william@osrfoundation.org>
@wjwwood
Copy link
Member

wjwwood commented Sep 6, 2018

CI:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@wjwwood
Copy link
Member

wjwwood commented Sep 7, 2018

I think the only thing blocking this right now is the resolution of what to do w.r.t. the save button's behavior. I'll be around tonight to follow up and make more CI jobs to hopefully merge it.

- Clicking on the transformers view, sometimes the clicked
  event is only sent to the underlying property, not the tree view
- This results in weird behaviour of the gui
- With this fix, it can only (rarely) happen that the click does nothing
@Martin-Idel-SI
Copy link
Contributor

Martin-Idel-SI commented Sep 7, 2018

Ok, I implemented and documented the workaround. Tested it locally and it seems to work as intended. CI:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@wjwwood
Copy link
Member

wjwwood commented Sep 7, 2018

I pushed a style fixup, but it doesn't affect code, so the CI is valid. Consider it merged if the CI is green. I'll merge it in the morning.

Signed-off-by: William Woodall <william@osrfoundation.org>
@wjwwood
Copy link
Member

wjwwood commented Sep 8, 2018

Sorry, I had a trailing whitespace in my change, and there's some strange test failures listed on the linux job, I'm running another CI to confirm:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

@wjwwood wjwwood merged commit 48c900d into ros2:ros2 Sep 8, 2018
@wjwwood wjwwood removed the in review Waiting for review (Kanban column) label Sep 8, 2018
@Martin-Idel-SI Martin-Idel-SI deleted the feature/use_pluginlib_for_frame_transformer branch September 10, 2018 06:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants