moveit2
The MoveIt Motion Planning Framework for ROS 2.
plan_components_builder.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2018 Pilz GmbH & Co. KG
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 Pilz GmbH & Co. KG 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 
36 
37 #include <cassert>
38 
40 
42 {
43 std::vector<robot_trajectory::RobotTrajectoryPtr> PlanComponentsBuilder::build() const
44 {
45  std::vector<robot_trajectory::RobotTrajectoryPtr> res_vec{ traj_cont_ };
46  if (traj_tail_)
47  {
48  assert(!res_vec.empty());
49  appendWithStrictTimeIncrease(*(res_vec.back()), *traj_tail_);
50  }
51  return res_vec;
52 }
53 
54 void PlanComponentsBuilder::appendWithStrictTimeIncrease(robot_trajectory::RobotTrajectory& result,
56 {
57  if (result.empty() ||
59  result.getGroupName(), ROBOT_STATE_EQUALITY_EPSILON))
60  {
61  result.append(source, 0.0);
62  return;
63  }
64 
65  for (size_t i = 1; i < source.getWayPointCount(); ++i)
66  {
68  }
69 }
70 
71 void PlanComponentsBuilder::blend(const planning_scene::PlanningSceneConstPtr& planning_scene,
72  const robot_trajectory::RobotTrajectoryPtr& other, const double blend_radius)
73 {
74  if (!blender_)
75  {
76  throw NoBlenderSetException("No blender set");
77  }
78 
79  assert(other->getGroupName() == traj_tail_->getGroupName());
80 
82 
83  blend_request.first_trajectory = traj_tail_;
84  blend_request.second_trajectory = other;
85  blend_request.blend_radius = blend_radius;
86  blend_request.group_name = traj_tail_->getGroupName();
87  blend_request.link_name = getSolverTipFrame(model_->getJointModelGroup(blend_request.group_name));
88 
90  if (!blender_->blend(planning_scene, blend_request, blend_response))
91  {
92  throw BlendingFailedException("Blending failed");
93  }
94 
95  // Append the new trajectory elements
96  appendWithStrictTimeIncrease(*(traj_cont_.back()), *blend_response.first_trajectory);
97  traj_cont_.back()->append(*blend_response.blend_trajectory, 0.0);
98  // Store the last new trajectory element for future processing
99  traj_tail_ = blend_response.second_trajectory; // first for next blending segment
100 }
101 
102 void PlanComponentsBuilder::append(const planning_scene::PlanningSceneConstPtr& planning_scene,
103  const robot_trajectory::RobotTrajectoryPtr& other, const double blend_radius)
104 {
105  if (!model_)
106  {
107  throw NoRobotModelSetException("No robot model set");
108  }
109 
110  if (!traj_tail_)
111  {
112  traj_tail_ = other;
113  // Reserve space in container for new trajectory
114  traj_cont_.emplace_back(std::make_shared<robot_trajectory::RobotTrajectory>(model_, other->getGroupName()));
115  return;
116  }
117 
118  // Create new trajectory for every group change
119  if (other->getGroupName() != traj_tail_->getGroupName())
120  {
121  appendWithStrictTimeIncrease(*(traj_cont_.back()), *traj_tail_);
122  traj_tail_ = other;
123  // Create new container element
124  traj_cont_.emplace_back(std::make_shared<robot_trajectory::RobotTrajectory>(model_, other->getGroupName()));
125  return;
126  }
127 
128  // No blending
129  if (blend_radius <= 0.0)
130  {
131  appendWithStrictTimeIncrease(*(traj_cont_.back()), *traj_tail_);
132  traj_tail_ = other;
133  return;
134  }
135 
136  blend(planning_scene, other, blend_radius);
137 }
138 
139 } // namespace pilz_industrial_motion_planner
std::vector< robot_trajectory::RobotTrajectoryPtr > build() const
void append(const planning_scene::PlanningSceneConstPtr &planning_scene, const robot_trajectory::RobotTrajectoryPtr &other, const double blend_radius)
Appends the specified trajectory to the trajectory container under construction.
Maintain a sequence of waypoints and the time durations between these waypoints.
const std::string & getGroupName() const
RobotTrajectory & addSuffixWayPoint(const moveit::core::RobotState &state, double dt)
Add a point to the trajectory.
const moveit::core::RobotState & getFirstWayPoint() const
RobotTrajectory & append(const RobotTrajectory &source, double dt, size_t start_index=0, size_t end_index=std::numeric_limits< std::size_t >::max())
Add a specified part of a trajectory to the end of the current trajectory. The default (when start_in...
double getWayPointDurationFromPrevious(std::size_t index) const
const moveit::core::RobotState & getWayPoint(std::size_t index) const
const moveit::core::RobotState & getLastWayPoint() const
bool isRobotStateEqual(const moveit::core::RobotState &state1, const moveit::core::RobotState &state2, const std::string &joint_group_name, double epsilon)
Check if the two robot states have the same joint position/velocity/acceleration.
This namespace includes the central class for representing planning contexts.