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.
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