moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
moveit_cpp.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2022, Peter David Fagan
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *********************************************************************/
34
35/* Author: Peter David Fagan */
36
37#include "moveit_cpp.hpp"
38#include <pybind11/pytypes.h>
40#include <string>
41
42namespace moveit_py
43{
44namespace bind_moveit_cpp
45{
46rclcpp::Logger getLogger()
47{
48 return moveit::getLogger("moveit.py.cpp_initializer");
49}
50
51std::shared_ptr<moveit_cpp::PlanningComponent>
52getPlanningComponent(std::shared_ptr<moveit_cpp::MoveItCpp>& moveit_cpp_ptr, const std::string& planning_component)
53{
54 return std::make_shared<moveit_cpp::PlanningComponent>(planning_component, moveit_cpp_ptr);
55}
56
57void initMoveitPy(py::module& m)
58{
59 auto utils = py::module::import("moveit.utils");
60
61 py::class_<moveit_cpp::MoveItCpp, std::shared_ptr<moveit_cpp::MoveItCpp>>(m, "MoveItPy", R"(
62 The MoveItPy class is the main interface to the MoveIt Python API. It is a wrapper around the MoveIt C++ API.
63 )")
64
65 .def(py::init([](const std::string& node_name, const std::string& name_space,
66 const std::vector<std::string>& launch_params_filepaths, const py::object& config_dict,
67 bool provide_planning_service,
68 const std::optional<std::map<std::string, std::string>>& remappings) {
69 // This section is used to load the appropriate node parameters before spinning a moveit_cpp instance
70 // Priority is given to parameters supplied directly via a config_dict, followed by launch parameters
71 // and finally no supplied parameters.
72 std::vector<std::string> launch_arguments;
73 if (!config_dict.is(py::none()))
74 {
75 auto utils = py::module::import("moveit.utils");
76 // TODO (peterdavidfagan): replace python method with C++ method
77 std::string params_filepath =
78 utils.attr("create_params_file_from_dict")(config_dict, node_name).cast<std::string>();
79 launch_arguments = { "--ros-args", "--params-file", params_filepath };
80 }
81 else if (!launch_params_filepaths.empty())
82 {
83 launch_arguments = { "--ros-args" };
84 for (const auto& launch_params_filepath : launch_params_filepaths)
85 {
86 launch_arguments.push_back("--params-file");
87 launch_arguments.push_back(launch_params_filepath);
88 }
89 }
90
91 if (remappings.has_value())
92 {
93 for (const auto& [key, value] : *remappings)
94 {
95 std::string argument = key;
96 argument.append(":=").append(value);
97 launch_arguments.push_back("--remap");
98 launch_arguments.push_back(std::move(argument));
99 }
100 }
101
102 // Initialize ROS, pass launch arguments with rclcpp::init()
103 if (!rclcpp::ok())
104 {
105 std::vector<const char*> chars;
106 chars.reserve(launch_arguments.size());
107 for (const auto& arg : launch_arguments)
108 {
109 chars.push_back(arg.c_str());
110 }
111
112 rclcpp::init(launch_arguments.size(), chars.data());
113 RCLCPP_INFO(getLogger(), "Initialize rclcpp");
114 }
115
116 // Build NodeOptions
117 RCLCPP_INFO(getLogger(), "Initialize node parameters");
118 rclcpp::NodeOptions node_options;
119 node_options.allow_undeclared_parameters(true)
120 .automatically_declare_parameters_from_overrides(true)
121 .arguments(launch_arguments);
122
123 RCLCPP_INFO(getLogger(), "Initialize node and executor");
124 rclcpp::Node::SharedPtr node = rclcpp::Node::make_shared(node_name, name_space, node_options);
125 std::shared_ptr<rclcpp::executors::SingleThreadedExecutor> executor =
126 std::make_shared<rclcpp::executors::SingleThreadedExecutor>();
127
128 RCLCPP_INFO(getLogger(), "Spin separate thread");
129 auto spin_node = [node, executor]() {
130 executor->add_node(node);
131 executor->spin();
132 };
133 std::thread execution_thread(spin_node);
134 execution_thread.detach();
135
136 auto custom_deleter = [executor](moveit_cpp::MoveItCpp* moveit_cpp) {
137 executor->cancel();
138 rclcpp::shutdown();
139 delete moveit_cpp;
140 };
141
142 std::shared_ptr<moveit_cpp::MoveItCpp> moveit_cpp_ptr(new moveit_cpp::MoveItCpp(node), custom_deleter);
143
144 if (provide_planning_service)
145 {
146 moveit_cpp_ptr->getPlanningSceneMonitorNonConst()->providePlanningSceneService();
147 };
148
149 return moveit_cpp_ptr;
150 }),
151 py::arg("node_name") = "moveit_py", py::arg("name_space") = "",
152 py::arg("launch_params_filepaths") =
153 utils.attr("get_launch_params_filepaths")().cast<std::vector<std::string>>(),
154 py::arg("config_dict") = py::none(), py::arg("provide_planning_service") = true,
155 py::arg("remappings") = py::none(), py::return_value_policy::take_ownership,
156 R"(
157 Initialize moveit_cpp node and the planning scene service.
158 )")
159 .def("execute",
160 py::overload_cast<const robot_trajectory::RobotTrajectoryPtr&, const std::vector<std::string>&>(
162 py::arg("robot_trajectory"), py::arg("controllers"), py::call_guard<py::gil_scoped_release>(),
163 R"(
164 Execute a trajectory (planning group is inferred from robot trajectory object).
165 )")
166 .def("get_planning_component", &moveit_py::bind_moveit_cpp::getPlanningComponent,
167 py::arg("planning_component_name"), py::return_value_policy::take_ownership,
168 R"(
169 Creates a planning component instance.
170 Args:
171 planning_component_name (str): The name of the planning component.
172 Returns:
173 :py:class:`moveit_py.planning.PlanningComponent`: A planning component instance corresponding to the provided plan component name.
174 )")
175
176 .def(
177 "shutdown", [](std::shared_ptr<moveit_cpp::MoveItCpp>& /*moveit_cpp*/) { rclcpp::shutdown(); },
178 R"(
179 Shutdown the moveit_cpp node.
180 )")
181
182 .def("get_planning_scene_monitor", &moveit_cpp::MoveItCpp::getPlanningSceneMonitorNonConst,
183 py::return_value_policy::reference,
184 R"(
185 Returns the planning scene monitor.
186 )")
187
188 .def("get_trajectory_execution_manager", &moveit_cpp::MoveItCpp::getTrajectoryExecutionManagerNonConst,
189 py::return_value_policy::reference,
190 R"(
191 Returns the trajectory execution manager.
192 )")
193
194 .def("get_robot_model", &moveit_cpp::MoveItCpp::getRobotModel, py::return_value_policy::reference,
195 R"(
196 Returns robot model.
197 )");
198}
199} // namespace bind_moveit_cpp
200} // namespace moveit_py
moveit_controller_manager::ExecutionStatus execute(const robot_trajectory::RobotTrajectoryPtr &robot_trajectory, bool blocking, const std::vector< std::string > &controllers=std::vector< std::string >())
Execute a trajectory on the planning group specified by the robot's trajectory using the trajectory e...
moveit::core::RobotModelConstPtr getRobotModel() const
Get the RobotModel object.
planning_scene_monitor::PlanningSceneMonitorPtr getPlanningSceneMonitorNonConst()
trajectory_execution_manager::TrajectoryExecutionManagerPtr getTrajectoryExecutionManagerNonConst()
std::shared_ptr< moveit_cpp::PlanningComponent > getPlanningComponent(std::shared_ptr< moveit_cpp::MoveItCpp > &moveit_cpp_ptr, const std::string &planning_component)
rclcpp::Logger getLogger()
void initMoveitPy(py::module &m)
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
Definition logger.cpp:79