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

[Servo] Port moveit_servo to ROS2 #248

Merged
merged 2 commits into from
Aug 24, 2020

Conversation

AdamPettinger
Copy link
Contributor

Description

This is a huge PR for porting moveit_servo to ROS2:

  1. Ports the source
  2. Adds examples (C++ interface, composable node interface, teleoperation demo for gamepad)
  3. Adds integration and unit tests

@AndyZe @tylerjw

Currently relies on moveit_resources, but I understand that might change soon. When it does, I will update and push here to use the new version

Servo Teleop Gif

Copy link
Member

@henningkayser henningkayser left a comment

Choose a reason for hiding this comment

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

Just a very quick first round. Great work @AdamPettinger this looks very high quality with all the documentation, tests, examples. I'll give this a more in-depth review and testing the next days. Your launch files look like we could get some best practices out of it.

moveit_ros/moveit_servo/CMakeLists.txt Outdated Show resolved Hide resolved
moveit_ros/moveit_servo/CMakeLists.txt Outdated Show resolved Hide resolved

find_package(catkin REQUIRED COMPONENTS
set(LIBRARY_NAME moveit_servo)
Copy link
Member

Choose a reason for hiding this comment

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

I like the idea of using variables like this. Alternatively, we could follow the ROS 1 convention is to use patterns like ${PROJECT_NAME}_lib, ${PROJECT_NAME}_server.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't mind either way. There are other variables set here which don't fit nicely into ${PROJECT_NAME}_lib or ${PROJECT_NAME}_server

moveit_ros/moveit_servo/CMakeLists.txt Outdated Show resolved Hide resolved
moveit_ros/moveit_servo/CMakeLists.txt Outdated Show resolved Hide resolved
moveit_ros/moveit_servo/src/collision_check.cpp Outdated Show resolved Hide resolved
@AdamPettinger
Copy link
Contributor Author

Your launch files look like we could get some best practices out of it.

Agree @henningkayser. I definitely want to make those changes. I am just not sure what exactly those best practices are (or if they have even decided?) 😃

Copy link
Member

@AndyZe AndyZe left a comment

Choose a reason for hiding this comment

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

Looks really good. Just some nitpicks and questions

moveit_ros/moveit_servo/CMakeLists.txt Show resolved Hide resolved
moveit_ros/moveit_servo/config/panda_simulated_config.yaml Outdated Show resolved Hide resolved
moveit_ros/moveit_servo/doc/running_the_demos.md Outdated Show resolved Hide resolved
moveit_ros/moveit_servo/doc/running_the_demos.md Outdated Show resolved Hide resolved
moveit_ros/moveit_servo/doc/servo_tutorial.md Outdated Show resolved Hide resolved
moveit_ros/moveit_servo/src/collision_check.cpp Outdated Show resolved Hide resolved
moveit_ros/moveit_servo/test/publish_fake_jog_commands.cpp Outdated Show resolved Hide resolved
Copy link
Member

@AndyZe AndyZe left a comment

Choose a reason for hiding this comment

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

Overall I'm shocked at how thorough the tests are. Good job! I'll probably come back to nitpick a bit more, then test it

@@ -674,75 +688,80 @@ double ServoCalcs::velocityScalingFactorForSingularity(const Eigen::VectorXd& co

void ServoCalcs::enforceSRDFAccelVelLimits(Eigen::ArrayXd& delta_theta)
Copy link
Member

Choose a reason for hiding this comment

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

let's definitely make sure the velocity limit enforcement gets updated, like we discussed. Here's the ROS1 PR:

moveit/moveit#2260

{
// "Load" parameters from yaml as node parameters
std::string robot_description_string, srdf_string;
loadModelFile("panda_description/urdf/panda.urdf", robot_description_string);
Copy link
Member

@henningkayser henningkayser Aug 19, 2020

Choose a reason for hiding this comment

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

Better use the convenience functions from moveit_test_utils to load your robot model.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Servo is looking for the URDF and SRDF as parameters (strings). To set that for testing I was doing:

loadModelFile("panda_description/urdf/panda.urdf", robot_description_string);
loadModelFile("panda_moveit_config/config/panda.srdf", srdf_string);
node_->declare_parameter<std::string>("robot_description", robot_description_string);
node_->declare_parameter<std::string>("robot_description_semantic", srdf_string);

I don't see a way in the moveit_test_utils to give the path to the file and get back the string for loading as a parameter, but maybe I am missing something?

Copy link
Member

Choose a reason for hiding this comment

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

If you only want to use a moveit_resources package moveit_test_utils is the way to go. If you want to support any robot using the robot_description parameter, the PSM (or the RobotModelLoader) supports this without anything extra and the moveit_resources default should be passed with the launch file. If your actual use case is not covered, maybe it should go into moveit_test_utils.

Copy link
Member

Choose a reason for hiding this comment

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

I see, moveit_resources doesn't really help because the PSM expects either the robot_description parameter or a RobotModelLoader (not the RobotModel). Maybe it would still be a good idea to move a convenience function for this to test utils. Something that declares the robot description parameters from a default package and optionally provides you with the loader instance.

bool got_param = false;
try
{
node->declare_parameter<T>(param_name, T{});
Copy link
Member

Choose a reason for hiding this comment

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

I don't really understand why this should be necessary, but maybe I just didn't get the API right. I thought declare_parameter() already returns the correctly typed parameter value (default value or override from yaml) where trivial casts have already been applied (i.e. if you declare a double, an int should be casted to one). If value conversion is not successful, declare_parameter() will throw an InvalidParameterValueException. After declaring a parameter, get_parameter() will always return true (at least that's what I thought) so we would actually have to verify that the output value doesn't match the possibly invalid default value. The false case would only check for the rclcpp::ParameterType::PARAMETER_NOT_SET flag which is only used if undeclared parameters are allowed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think you are right, I will look into this. In general I am unsure how to tell if a parameter was successfully set from yaml vs just taken as the default value. There are some parameters in servo that can work as the default, but the user might not want that. And a bunch of course that cannot be default, and should be caught here as invalid

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, I did some reworking on the parameter reading. You were correct about the get_parameter() always returning true after the declare_parameter() call. From the documentation, it does seem like the type casting with declare_parameter() would work, but I couldn't get it to and was still struggling with some doubles being read as ints (which could be fixed by writing 1.0 instead of 1 in the yaml, but that is definitely confusing for a user). Example of what didn't work, and still threw the error the catch looks for here:
parameters->low_pass_filter_coeff = node->declare_parameter<double>(ns + ".low_pass_filter_coeff", -1);

The change I just made turns that template function (declareAndGetParam()) into a void return and basically just uses it to catch the double-int problem.

Copy link
Member

@davetcoleman davetcoleman left a comment

Choose a reason for hiding this comment

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

Incredible test coverage, great work!

@@ -34,7 +34,7 @@
* 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.
*******************************************************************************/
*******************************************************************************/

Copy link
Member

Choose a reason for hiding this comment

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

Possible out of scope for this PR, but algorithm-heavy files like this would be better to live in moveit_core and only the ROS bindings are in moveit_ros. Would make these components much more reusable

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am ok with moving some of these out, in this PR or a followup one

@@ -34,7 +34,7 @@
* 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.
*******************************************************************************/
*******************************************************************************/
Copy link
Member

Choose a reason for hiding this comment

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

This is a generic utility and would much better live in this folder for all of moveit to use:

https://github.com/ros-planning/moveit/tree/master/moveit_core/macros/include/moveit/macros

@@ -34,41 +34,46 @@
* 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.
*******************************************************************************/
*******************************************************************************/

Copy link
Member

Choose a reason for hiding this comment

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

Can this file also live in moveit_core?

@@ -0,0 +1,80 @@
import os
Copy link
Member

Choose a reason for hiding this comment

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

Would this be better to live in moveit_tutorials?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think so, but I don't see anywhere for moveit2_tutorials yet

@AdamPettinger
Copy link
Contributor Author

Force pushed to rebase my work on recent master changes, but did not go all the way to the master branch tip as I am experiencing 2 issues:

  1. Duplicate nodes, see Duplicate nodes in run_moveit_cpp demo #252
  2. Seg faults while destructing the unit test fixture that cause the tests to fail (I think this might be related to the above issue as well: the planning_scene_monitor destructor is where the faults happen)

Copy link
Member

@AndyZe AndyZe left a comment

Choose a reason for hiding this comment

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

Just tested all of the demos. My only complaint is that CPU load is higher than it should be (the ROS1 version was at ~20%, the ROS2 version is about 200%). But, that might be a ROS2 middleware issue and not even your fault. Well done!

Copy link
Member

@tylerjw tylerjw left a comment

Choose a reason for hiding this comment

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

Reading through this it looks really good. Thank you for doing this! 🥇

Comment on lines 182 to +184
private_executor_->cancel();
if (private_executor_thread_.joinable())
private_executor_thread_.join();
Copy link
Member

Choose a reason for hiding this comment

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

Note for others, this fixed a segfault. The issue was that cancel just asks the executor to exit, it doesn't wait for it to happen which means that the memory was being freed while it was still being used.

@tylerjw
Copy link
Member

tylerjw commented Aug 21, 2020

Unused parameter warnings and clang-format is why it is failing CI.

I played with the demo using an xbox controller and it is really awesome.

@tylerjw
Copy link
Member

tylerjw commented Aug 22, 2020

It looks like the clang-tidy CI failures are mostly just naming convention issues: https://travis-ci.com/github/ros-planning/moveit2/jobs/376436677

I'm looking into the test failures to see if I can understand them.

@tylerjw
Copy link
Member

tylerjw commented Aug 23, 2020

Created a small PR for some slight adjustments to tests to make them run faster and pass: AdamPettinger#2

@tylerjw
Copy link
Member

tylerjw commented Aug 23, 2020

I'm happy to merge this but would like this rebased into a single (or two if you want my few changes separate) commits. The primary reason is to keep the commit history on master nice and make it easier when we go to release and create changelists. Here is my suggestion for the commit message (please change this to include anything you think would be important to include in the changelist):

Port of moveit_servo

* Ports the source from MoveIt
* Adds examples (C++ interface, composable node interface, teleoperation demo for gamepad)
* Adds integration and unit tests

The easiest way to do this would be to do an interactive rebase and squash most of the commits into one. The changes you made after mine can probably be applied in a different order (squashed into your changes) if you want to make this in two commits.

AdamPettinger and others added 2 commits August 23, 2020 20:16
* Ports the source from MoveIt
* Adds examples (C++ interface, composable node interface, teleoperation demo for gamepad)
* Adds integration and unit tests
@tylerjw tylerjw merged commit b85ba87 into moveit:master Aug 24, 2020
henningkayser added a commit that referenced this pull request Aug 24, 2020
@AdamPettinger AdamPettinger deleted the pr-rebase_on_foxy branch June 2, 2021 19:58
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

5 participants