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

Add tutorial for warehouse_ros(_sqlite) #101

Merged
merged 5 commits into from
Oct 14, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
230 changes: 230 additions & 0 deletions doc/persistent_scenes_and_states/move_group.launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
import os
import yaml
from launch import LaunchDescription
from launch_ros.actions import Node
from launch.actions import ExecuteProcess
from ament_index_python.packages import get_package_share_directory
import xacro


def load_file(package_name, file_path):
package_path = get_package_share_directory(package_name)
absolute_file_path = os.path.join(package_path, file_path)

try:
with open(absolute_file_path, "r") as file:
return file.read()
except EnvironmentError: # parent of IOError, OSError *and* WindowsError where available
return None


def load_yaml(package_name, file_path):
package_path = get_package_share_directory(package_name)
absolute_file_path = os.path.join(package_path, file_path)

try:
with open(absolute_file_path, "r") as file:
return yaml.safe_load(file)
except EnvironmentError: # parent of IOError, OSError *and* WindowsError where available
return None


def generate_launch_description():

# planning_context
robot_description_config = xacro.process_file(
os.path.join(
get_package_share_directory("moveit_resources_panda_moveit_config"),
"config",
"panda.urdf.xacro",
)
)
robot_description = {"robot_description": robot_description_config.toxml()}

robot_description_semantic_config = load_file(
"moveit_resources_panda_moveit_config", "config/panda.srdf"
)
robot_description_semantic = {
"robot_description_semantic": robot_description_semantic_config
}

kinematics_yaml = load_yaml(
"moveit_resources_panda_moveit_config", "config/kinematics.yaml"
)
robot_description_kinematics = {"robot_description_kinematics": kinematics_yaml}

# Planning Functionality
ompl_planning_pipeline_config = {
"move_group": {
"planning_plugin": "ompl_interface/OMPLPlanner",
"request_adapters": """default_planner_request_adapters/AddTimeOptimalParameterization default_planner_request_adapters/FixWorkspaceBounds default_planner_request_adapters/FixStartStateBounds default_planner_request_adapters/FixStartStateCollision default_planner_request_adapters/FixStartStatePathConstraints""",
"start_state_max_bounds_error": 0.1,
}
}
ompl_planning_yaml = load_yaml(
"moveit_resources_panda_moveit_config", "config/ompl_planning.yaml"
)
ompl_planning_pipeline_config["move_group"].update(ompl_planning_yaml)

# Trajectory Execution Functionality
moveit_simple_controllers_yaml = load_yaml(
"moveit_resources_panda_moveit_config", "config/panda_controllers.yaml"
)
moveit_controllers = {
"moveit_simple_controller_manager": moveit_simple_controllers_yaml,
"moveit_controller_manager": "moveit_simple_controller_manager/MoveItSimpleControllerManager",
}

trajectory_execution = {
"moveit_manage_controllers": True,
"trajectory_execution.allowed_execution_duration_scaling": 1.2,
"trajectory_execution.allowed_goal_duration_margin": 0.5,
"trajectory_execution.allowed_start_tolerance": 0.01,
}

planning_scene_monitor_parameters = {
"publish_planning_scene": True,
"publish_geometry_updates": True,
"publish_state_updates": True,
"publish_transforms_updates": True,
}

## BEGIN_SUB_TUTORIAL add_config
## * Add a dictionary with the warehouse_ros options
warehouse_ros_config = {
# For warehouse_ros_sqlite
"warehouse_plugin": "warehouse_ros_sqlite::DatabaseConnection",
"warehouse_host": "/path/to/my/warehouse_db.sqlite",
henningkayser marked this conversation as resolved.
Show resolved Hide resolved
# For warehouse_ros_mongodb
"warehouse_port": 33829,
"warehouse_host": "localhost",
"warehouse_plugin": "warehouse_ros_mongo::MongoDatabaseConnection",
gleichdick marked this conversation as resolved.
Show resolved Hide resolved
}
## END_SUB_TUTORIAL

# Start the actual move_group node/action server
## BEGIN_SUB_TUTORIAL set_config_move_group
## * Add it to the Move Group config
run_move_group_node = Node(
package="moveit_ros_move_group",
executable="move_group",
output="screen",
parameters=[
robot_description,
robot_description_semantic,
kinematics_yaml,
ompl_planning_pipeline_config,
trajectory_execution,
moveit_controllers,
planning_scene_monitor_parameters,
# here
warehouse_ros_config,
],
)
## END_SUB_TUTORIAL

# RViz
rviz_config_file = (
get_package_share_directory("moveit2_tutorials") + "/launch/move_group.rviz"
)

## BEGIN_SUB_TUTORIAL set_config_rviz
## * and to the RViz config
rviz_node = Node(
package="rviz2",
executable="rviz2",
name="rviz2",
output="log",
arguments=["-d", rviz_config_file],
parameters=[
robot_description,
robot_description_semantic,
ompl_planning_pipeline_config,
kinematics_yaml,
# here
warehouse_ros_config,
],
)
## END_SUB_TUTORIAL

# Static TF
static_tf = Node(
package="tf2_ros",
executable="static_transform_publisher",
name="static_transform_publisher",
output="log",
arguments=["0.0", "0.0", "0.0", "0.0", "0.0", "0.0", "world", "panda_link0"],
)

# Publish TF
robot_state_publisher = Node(
package="robot_state_publisher",
executable="robot_state_publisher",
name="robot_state_publisher",
output="both",
parameters=[robot_description],
)

# ros2_control using FakeSystem as hardware
ros2_controllers_path = os.path.join(
get_package_share_directory("moveit_resources_panda_moveit_config"),
"config",
"panda_ros_controllers.yaml",
)
ros2_control_node = Node(
package="controller_manager",
executable="ros2_control_node",
parameters=[robot_description, ros2_controllers_path],
output={
"stdout": "screen",
"stderr": "screen",
},
)

# Load controllers
load_controllers = []
for controller in [
"panda_arm_controller",
"panda_hand_controller",
"joint_state_controller",
henningkayser marked this conversation as resolved.
Show resolved Hide resolved
]:
load_controllers += [
ExecuteProcess(
cmd=["ros2 run controller_manager spawner.py {}".format(controller)],
shell=True,
output="screen",
)
]

# Warehouse mongodb server
## BEGIN_SUB_TUTORIAL start_mongodb_server
## * start the MongoDB server (if necessary)
mongodb_server_node = Node(
henningkayser marked this conversation as resolved.
Show resolved Hide resolved
package="warehouse_ros_mongo",
executable="mongo_wrapper_ros.py",
parameters=[
warehouse_ros_config,
],
output="screen",
)
## END_SUB_TUTORIAL

return LaunchDescription(
[
rviz_node,
static_tf,
robot_state_publisher,
run_move_group_node,
ros2_control_node,
mongodb_server_node,
]
+ load_controllers
)


## BEGIN_TUTORIAL
## CALL_SUB_TUTORIAL add_config
## CALL_SUB_TUTORIAL set_config_move_group
## CALL_SUB_TUTORIAL set_config_rviz
## CALL_SUB_TUTORIAL start_mongodb_server
## END_TUTORIAL
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not familiar with the current MoveIt launch file code in ROS2 (In my naive opinion it's a horrible and entirely useless pile of crap that does not scale), so I can't review this file at all.

Please review this file @JafarAbdi @henningkayser
Do you really add these whole stacks to each and every tutorial?

Copy link
Member

Choose a reason for hiding this comment

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

All launch files will be simplified once moveit/moveit2#591 is merged. No need to adapt this launch file, though.

59 changes: 59 additions & 0 deletions doc/persistent_scenes_and_states/persistent_scenes_and_states.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
Persistent Planning Scenes and Robot States
===========================================

The "MotionPlanning" plugin of RViz offers the possibility to save
complete planning scenes and robot states persistently.
Currently, two storage plugins (based on
`warehouse_ros <https://github.com/ros-planning/warehouse_ros>`_) are available:

* `warehouse_ros_mongo <https://github.com/ros-planning/warehouse_ros_mongo>`_, which uses MongoDB as backend (default)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it makes sense to highlight this as the default.
If anything most new users of these methods will default to the simpler sqlite backend.

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 agree, but then we have to change all the demo files and the templates for the MSA. This would be a breaking change, maybe postpone it to the next distro (H Turtle)?

Copy link
Contributor

@v4hn v4hn Aug 10, 2021

Choose a reason for hiding this comment

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

There is no official MSA for MoveIt2 yet, so we still have all the flexibility there as far as I know. :)
But yes, in MoveIt the config templates mention mongodb in multiple places, so de facto that makes it the default.
However, I would still prefer to remove the (default) part to not bias potential users into thinking mongodb might be better.

* `warehouse_ros_sqlite <https://github.com/gleichdick/warehouse_ros_sqlite>`_, which uses SQLite as backend

You can install both of them with your favourite package manager
(e.g. ``apt-get install ros-foxy-warehouse-ros-mongo``) or
`build them from source <../getting_started/getting_started.html>`_
(of course, you'll have to check out the corresponding repository into your ``src`` folder for that).

Storage plugin selection
------------------------

The storage plugin is determined by the parameter ``warehouse_plugin``.
Valid options are ``warehouse_ros_mongo::MongoDatabaseConnection`` for MongoDB and
``warehouse_ros_sqlite::DatabaseConnection`` for SQLite.
Furthermore, the parameters ``warehouse_host`` and ``warehouse_port`` configure the connection details.
In case of the SQLite plugin, ``warehouse_host`` contains the path of the database file.
v4hn marked this conversation as resolved.
Show resolved Hide resolved
They have to be set in the launch file (e. g. ``move_group.launch.py``) as followed:

.. tutorial-formatter:: ./move_group.launch.py

You can find the launch file :codedir:`here in the tutorials GitHub repository <persistent_scenes_and_states/move_group.launch.py>`
or (unmodified) in your workspace at ``install/moveit2_tutorials/share/moveit2_tutorials/launch/demo.launch.py``.

Connecting to the storage backend
---------------------------------

After choosing the storage plugin and configuring the launch.py file,
run RViz using ::

ros2 launch moveit2_tutorials demo.launch.py

In RViz, navigate to the "Context" tab of the "MotionPlanning" window.
Verify the connetion details (host/port for MongoDB, file path for SQLite)
gleichdick marked this conversation as resolved.
Show resolved Hide resolved
and click on "Connect".

.. image:: rviz_connect.png
:width: 600px

After that, a dialogue box will appear and ask you whether you'd like to erase all current
states and scenes in RViz (not in the database, the persistent data is not affected by that).
gleichdick marked this conversation as resolved.
Show resolved Hide resolved

Saving/Loading scenes and states
--------------------------------

Now that you connected successfully,
you can save and restore robot states and planned scenes.
This can be done in the "Stored Scenes" resp. "Stored States" tab in RViz.

To save a start state, drag the green manipulator to the correct position and click "Save Start".
The goal state (orange manipulator) can be saved with the "Save Goal" button.
To restore a state, select it in the list and click on "Set as Start" resp. "Set as Goal".
Copy link
Contributor

Choose a reason for hiding this comment

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

the user experience is really horrible with this GUI... I just tried to use this for something productive.
But of course reworking the GUI is outside of the scope of this.

Binary file added doc/persistent_scenes_and_states/rviz_connect.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions doc/quickstart_in_rviz/quickstart_in_rviz_tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,5 @@ Next Tutorials
* To easily control your robot using Python, check out the `Move Group Python Interface <../move_group_python_interface/move_group_python_interface_tutorial.html>`_

* To create your own ``*_moveit_config`` package, check out the `Setup Assistant <../setup_assistant/setup_assistant_tutorial.html>`_

* Save and restore robot states from a database or from disk using `warehouse_ros <../persistent_scenes_and_states/persistent_scenes_and_states.html>`_
1 change: 1 addition & 0 deletions index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Configuration
doc/trajopt_planner/trajopt_planner_tutorial
doc/pilz_industrial_motion_planner/pilz_industrial_motion_planner
doc/planning_adapters/planning_adapters_tutorial.rst
doc/persistent_scenes_and_states/persistent_scenes_and_states

Miscellaneous
----------------------------
Expand Down