moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
evaluate_collision_checking_speed.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2012, Willow Garage, Inc.
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 Willow Garage 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: Ioan Sucan, Sachin Chitta */
36
37#include <chrono>
39#include <boost/program_options/parsers.hpp>
40#include <boost/program_options/variables_map.hpp>
41#include <thread>
43
44using namespace std::chrono_literals;
45
46namespace
47{
48rclcpp::Logger getLogger()
49{
50 return moveit::getLogger("moveit.ros.evaluate_collision_checking_speed");
51}
52} // namespace
53
54static const std::string ROBOT_DESCRIPTION = "robot_description";
55
56void runCollisionDetection(unsigned int id, unsigned int trials, const planning_scene::PlanningScene& scene,
57 const moveit::core::RobotState& state)
58{
59 RCLCPP_INFO(getLogger(), "Starting thread %u", id);
60 rclcpp::Clock clock(RCL_ROS_TIME);
62 rclcpp::Time start = clock.now();
63 for (unsigned int i = 0; i < trials; ++i)
64 {
66 scene.checkCollision(req, res, state);
67 }
68 double duration = (clock.now() - start).seconds();
69 RCLCPP_INFO(getLogger(), "Thread %u performed %lf collision checks per second", id,
70 static_cast<double>(trials) / duration);
71}
72
73int main(int argc, char** argv)
74{
75 rclcpp::init(argc, argv);
76 auto node = rclcpp::Node::make_shared("evaluate_collision_checking_speed");
77 moveit::setNodeLoggerName(node->get_name());
78
79 unsigned int nthreads = 2;
80 unsigned int trials = 10000;
81 boost::program_options::options_description desc;
82 desc.add_options()("nthreads", boost::program_options::value<unsigned int>(&nthreads)->default_value(nthreads),
83 "Number of threads to use")(
84 "trials", boost::program_options::value<unsigned int>(&trials)->default_value(trials),
85 "Number of collision checks to perform with each thread")("wait",
86 "Wait for a user command (so the planning scene can be "
87 "updated in the background)")("help", "this screen");
88 boost::program_options::variables_map vm;
89 boost::program_options::parsed_options po = boost::program_options::parse_command_line(argc, argv, desc);
90 boost::program_options::store(po, vm);
91 boost::program_options::notify(vm);
92
93 if (vm.count("help"))
94 {
95 std::cout << desc << '\n';
96 return 0;
97 }
98
99 rclcpp::executors::MultiThreadedExecutor executor;
100 executor.add_node(node);
101
102 planning_scene_monitor::PlanningSceneMonitor psm(node, ROBOT_DESCRIPTION);
103 if (psm.getPlanningScene())
104 {
105 if (vm.count("wait"))
106 {
108 psm.startSceneMonitor();
109 std::cout << "Listening to planning scene updates. Press Enter to continue ..." << '\n';
110 std::cin.get();
111 }
112 else
113 rclcpp::sleep_for(500ms);
114
115 std::vector<moveit::core::RobotStatePtr> states;
116 RCLCPP_INFO(node->get_logger(), "Sampling %u valid states...", nthreads);
117 for (unsigned int i = 0; i < nthreads; ++i)
118 {
119 // sample a valid state
120 moveit::core::RobotState* state = new moveit::core::RobotState(psm.getPlanningScene()->getRobotModel());
122 do
123 {
124 state->setToRandomPositions();
125 state->update();
127 psm.getPlanningScene()->checkCollision(req, res);
128 if (!res.collision)
129 break;
130 } while (true);
131 states.push_back(moveit::core::RobotStatePtr(state));
132 }
133
134 std::vector<std::thread*> threads;
135 runCollisionDetection(10, trials, *psm.getPlanningScene(), *states[0]);
136 for (unsigned int i = 0; i < states.size(); ++i)
137 {
138 threads.push_back(new std::thread([i, trials, &scene = *psm.getPlanningScene(), &state = *states[i]] {
139 return runCollisionDetection(i, trials, scene, state);
140 }));
141 }
142
143 for (unsigned int i = 0; i < states.size(); ++i)
144 {
145 threads[i]->join();
146 delete threads[i];
147 }
148 }
149 else
150 RCLCPP_ERROR(node->get_logger(), "Planning scene not configured");
151
152 return 0;
153}
Representation of a robot's state. This includes position, velocity, acceleration and effort.
Definition robot_state.h:90
void setToRandomPositions()
Set all joints to random values. Values will be within default bounds.
void update(bool force=false)
Update all transforms.
This class maintains the representation of the environment as seen by a planning instance....
void checkCollision(const collision_detection::CollisionRequest &req, collision_detection::CollisionResult &res)
Check whether the current state is in collision, and if needed, updates the collision transforms of t...
PlanningSceneMonitor Subscribes to the topic planning_scene.
void startSceneMonitor(const std::string &scene_topic=DEFAULT_PLANNING_SCENE_TOPIC)
Start the scene monitor (ROS topic-based)
void startWorldGeometryMonitor(const std::string &collision_objects_topic=DEFAULT_COLLISION_OBJECT_TOPIC, const std::string &planning_scene_world_topic=DEFAULT_PLANNING_SCENE_WORLD_TOPIC, const bool load_octomap_monitor=true)
Start the OccupancyMapMonitor and listening for:
const planning_scene::PlanningScenePtr & getPlanningScene()
Avoid this function! Returns an unsafe pointer to the current planning scene.
void runCollisionDetection(unsigned int id, unsigned int trials, const planning_scene::PlanningScene &scene, const moveit::core::RobotState &state)
int main(int argc, char **argv)
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
Definition logger.cpp:79
void setNodeLoggerName(const std::string &name)
Call once after creating a node to initialize logging namespaces.
Definition logger.cpp:73
Representation of a collision checking request.
Representation of a collision checking result.
bool collision
True if collision was found, false otherwise.