moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
union_constraint_sampler.cpp
Go to the documentation of this file.
1/*********************************************************************
2 * Software License Agreement (BSD License)
3 *
4 * Copyright (c) 2011, 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 */
36
39#include <rclcpp/logger.hpp>
40#include <rclcpp/logging.hpp>
41#include <algorithm>
43
44namespace constraint_samplers
45{
46namespace
47{
48rclcpp::Logger getLogger()
49{
50 return moveit::getLogger("moveit.core.union_constraint_sampler");
51}
52} // namespace
53
55{
56 bool operator()(const ConstraintSamplerPtr& a, const ConstraintSamplerPtr& b) const
57 {
58 const std::vector<std::string>& alinks = a->getJointModelGroup()->getUpdatedLinkModelNames();
59 const std::vector<std::string>& blinks = b->getJointModelGroup()->getUpdatedLinkModelNames();
60 std::set<std::string> a_updates(alinks.begin(), alinks.end());
61 std::set<std::string> b_updates(blinks.begin(), blinks.end());
62
63 bool a_contains_b = std::includes(a_updates.begin(), a_updates.end(), b_updates.begin(), b_updates.end());
64
65 bool b_contains_a = std::includes(b_updates.begin(), b_updates.end(), a_updates.begin(), a_updates.end());
66
67 // a contains b and sets are not equal
68 if (a_contains_b && !b_contains_a)
69 return true;
70 if (b_contains_a && !a_contains_b)
71 return false;
72
73 // sets are equal or disjoint
74 bool a_depends_on_b = false;
75 bool b_depends_on_a = false;
76 const std::vector<std::string>& fda = a->getFrameDependency();
77 const std::vector<std::string>& fdb = b->getFrameDependency();
78 for (std::size_t i = 0; i < fda.size() && !a_depends_on_b; ++i)
79 {
80 for (const std::string& blink : blinks)
81 {
82 if (blink == fda[i])
83 {
84 a_depends_on_b = true;
85 break;
86 }
87 }
88 }
89 for (std::size_t i = 0; i < fdb.size() && !b_depends_on_a; ++i)
90 {
91 for (const std::string& alink : alinks)
92 {
93 if (alink == fdb[i])
94 {
95 b_depends_on_a = true;
96 break;
97 }
98 }
99 }
100 if (b_depends_on_a && a_depends_on_b)
101 {
102 RCLCPP_WARN(getLogger(),
103 "Circular frame dependency! "
104 "Sampling will likely produce invalid results (sampling for groups '%s' and '%s')",
105 a->getJointModelGroup()->getName().c_str(), b->getJointModelGroup()->getName().c_str());
106 return true;
107 }
108 if (b_depends_on_a && !a_depends_on_b)
109 return true;
110 if (a_depends_on_b && !b_depends_on_a)
111 return false;
112
113 // prefer sampling JointConstraints first
114 JointConstraintSampler* ja = dynamic_cast<JointConstraintSampler*>(a.get());
115 JointConstraintSampler* jb = dynamic_cast<JointConstraintSampler*>(b.get());
116 if (ja && jb == nullptr)
117 return true;
118 if (jb && ja == nullptr)
119 return false;
120
121 // neither depends on either, so break ties based on group name
122 return (a->getJointModelGroup()->getName() < b->getJointModelGroup()->getName());
123 }
124};
125
126UnionConstraintSampler::UnionConstraintSampler(const planning_scene::PlanningSceneConstPtr& scene,
127 const std::string& group_name,
128 const std::vector<ConstraintSamplerPtr>& samplers)
129 : ConstraintSampler(scene, group_name), samplers_(samplers)
130{
131 // using stable sort to preserve order of equivalents
132 std::stable_sort(samplers_.begin(), samplers_.end(), OrderSamplers());
133
134 for (ConstraintSamplerPtr& sampler : samplers_)
135 {
136 const std::vector<std::string>& fds = sampler->getFrameDependency();
137 for (const std::string& fd : fds)
138 frame_depends_.push_back(fd);
139
140 RCLCPP_DEBUG(getLogger(), "Union sampler for group '%s' includes sampler for group '%s'", jmg_->getName().c_str(),
141 sampler->getJointModelGroup()->getName().c_str());
142 }
143}
144
146 unsigned int max_attempts)
147{
148 state = reference_state;
149 for (ConstraintSamplerPtr& sampler : samplers_)
150 {
151 // ConstraintSampler::sample returns states with dirty link transforms (because it only writes values)
152 // but requires a state with clean link transforms as input. This means that we need to clean the link
153 // transforms between calls to ConstraintSampler::sample.
154 state.updateLinkTransforms();
155 if (!sampler->sample(state, max_attempts))
156 return false;
157 }
158 return true;
159}
160
161} // end of namespace constraint_samplers
ConstraintSampler is an abstract base class that allows the sampling of a kinematic state for a parti...
std::vector< std::string > frame_depends_
Holds the set of frames that must exist in the reference state to allow samples to be drawn.
const moveit::core::JointModelGroup *const jmg_
Holds the joint model group associated with this constraint.
JointConstraintSampler is a class that allows the sampling of joints in a particular group of the rob...
bool sample(moveit::core::RobotState &state, const moveit::core::RobotState &reference_state, unsigned int max_attempts) override
Produces a sample from all configured samplers.
std::vector< ConstraintSamplerPtr > samplers_
Holder for sorted internal list of samplers.
UnionConstraintSampler(const planning_scene::PlanningSceneConstPtr &scene, const std::string &group_name, const std::vector< ConstraintSamplerPtr > &samplers)
Constructor, which will re-order its internal list of samplers on construction.
const std::string & getName() const
Get the name of the joint group.
Representation of a robot's state. This includes position, velocity, acceleration and effort.
Definition robot_state.h:90
void updateLinkTransforms()
Update the reference frame transforms for links. This call is needed before using the transforms of l...
The constraint samplers namespace contains a number of methods for generating samples based on a cons...
rclcpp::Logger getLogger(const std::string &name)
Creates a namespaced logger.
Definition logger.cpp:79
bool operator()(const ConstraintSamplerPtr &a, const ConstraintSamplerPtr &b) const