Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c86e3b2
Format max_velocity and max_acceleration for YAML output as float
AimanHaidar Oct 24, 2025
38aac46
make use of max_cartesian_speed in MotionSequenceRequest
AimanHaidar Nov 5, 2025
7d70a27
use feature in circ command
AimanHaidar Nov 5, 2025
0bb71f2
organize into function
AimanHaidar Nov 5, 2025
b28883e
Merge branch 'fix/joint-limits-crash' into dev
AimanHaidar Nov 7, 2025
ce9099d
add free path planner using composite kdl path
AimanHaidar Nov 7, 2025
a0bc8e4
fix include files and add it to plugin
AimanHaidar Nov 8, 2025
4e62e81
convert to roundedComposite
AimanHaidar Nov 8, 2025
e9f63ae
fix bug andadd check of near start point to curve tip
AimanHaidar Nov 8, 2025
4008bdc
fix bug in set max cart speed before set of path
AimanHaidar Nov 8, 2025
b8e8de3
Merge branch 'feature/use-max-cartesian-speed' into feature/free-path…
AimanHaidar Nov 8, 2025
99f146b
add check request validation
AimanHaidar Nov 8, 2025
24d27ce
add function to compute the max rounding circle radius
AimanHaidar Nov 9, 2025
84a8e94
add close points check to avoid Not_Feasable error
AimanHaidar Nov 9, 2025
749d7e4
add helper class for generate free paths
AimanHaidar Nov 10, 2025
440a77d
clean code and add copyright!
AimanHaidar Nov 10, 2025
c6a0389
Merge branch 'moveit:main' into feature/free-path-generator
AimanHaidar Nov 10, 2025
7e08974
handle colinear points errors
AimanHaidar Nov 10, 2025
5072fbd
correct error massages and fix bug
AimanHaidar Nov 22, 2025
9fc413a
restrict the rounding radius to not exceed KDL epsilon
AimanHaidar Nov 24, 2025
616d427
fix bug
AimanHaidar Nov 24, 2025
ab5d654
fix:compute rounding(blend) radius after filtering near points
AimanHaidar Nov 24, 2025
5f7a8ba
change name to polyline
AimanHaidar Dec 1, 2025
d5ce36c
change files' names
AimanHaidar Dec 1, 2025
b1df424
rename
AimanHaidar Dec 1, 2025
61c8742
fix jazzy-ci issue
AimanHaidar Dec 1, 2025
0120591
add test for the cartesian max speed
AimanHaidar Dec 2, 2025
ef3294f
Revert "Format max_velocity and max_acceleration for YAML output as f…
AimanHaidar Dec 2, 2025
7bd69b7
Merge branch 'main' into feature/free-path-generator
AimanHaidar Dec 3, 2025
d60d8dd
fix clang-tidy failures for rolling
AimanHaidar Dec 3, 2025
7ff2294
delete .h files
AimanHaidar Dec 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions moveit_planners/pilz_industrial_motion_planner/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,17 @@ ament_target_dependencies(planning_context_loader_circ
target_link_libraries(planning_context_loader_circ planning_context_loader_base
joint_limits_common trajectory_generation_common)

add_library(
planning_context_loader_polyline SHARED
src/planning_context_loader_polyline.cpp
src/trajectory_generator_polyline.cpp src/velocity_profile_atrap.cpp
src/path_polyline_generator.cpp)
ament_target_dependencies(planning_context_loader_polyline
${THIS_PACKAGE_INCLUDE_DEPENDS})
target_link_libraries(
planning_context_loader_polyline planning_context_loader_base
joint_limits_common trajectory_generation_common)

add_library(sequence_capability SHARED src/move_group_sequence_action.cpp
src/move_group_sequence_service.cpp)
ament_target_dependencies(sequence_capability ${THIS_PACKAGE_INCLUDE_DEPENDS})
Expand All @@ -153,6 +164,7 @@ install(
planning_context_loader_ptp
planning_context_loader_lin
planning_context_loader_circ
planning_context_loader_polyline
command_list_manager
sequence_capability
trajectory_generation_common
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*********************************************************************
* Software License Agreement (BSD License)
*
* Copyright (c) 2018 Pilz GmbH & Co. KG
* Copyright (c) 2025 Aiman Haidar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Pilz GmbH & Co. KG nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

#pragma once

#include <kdl/path.hpp>
#include <kdl/path_roundedcomposite.hpp>
#include <kdl/rotational_interpolation_sa.hpp>
#include <kdl/utilities/error.h>

#include <memory>

namespace pilz_industrial_motion_planner
{
/**
* @brief Generator class for KDL::Path_RoundedComposite from different polyline path
* representations
*/
class PathPolylineGenerator
{
public:
/**
* @brief set the path polyline from waypoints
*
*/
static std::unique_ptr<KDL::Path> polylineFromWaypoints(const KDL::Frame& start_pose,
const std::vector<KDL::Frame>& waypoints,
KDL::RotationalInterpolation* rot_interpo, double smoothness,
double eqradius);

/**
* @brief compute the maximum rounding radius from KDL::Path_RoundedComosite
* @param waypoints_: waypoints defining the path
* @param smoothness: smoothness level [0..1] scaling the maximum blend radius
* @return maximum blend radius
*/
static std::vector<KDL::Frame> filterWaypoints(const KDL::Frame& start_pose, const std::vector<KDL::Frame>& waypoints);
static double computeBlendRadius(const std::vector<KDL::Frame>& waypoints_, double smoothness);
static void checkConsecutiveColinearWaypoints(const KDL::Frame& p1, const KDL::Frame& p2, const KDL::Frame& p3);

private:
PathPolylineGenerator(){}; // no instantiation of this helper class!

static constexpr double MIN_SEGMENT_LENGTH{ 0.2e-3 };
static constexpr double MIN_SMOOTHNESS{ 0.01 };
static constexpr double MAX_SMOOTHNESS{ 0.99 };
static constexpr double MIN_COLINEAR_NORM{ 1e-9 };
};

class ErrorMotionPlanningColinearConsicutiveWaypoints : public KDL::Error_MotionPlanning
{
public:
const char* Description() const override
{
return "Three collinear consecutive waypoints."
" A Polyline Path cannot be created.";
}
int GetType() const override
{
return ERROR_CODE_COLINEAR_CONSECUTIVE_WAYPOINTS;
} // LCOV_EXCL_LINE

private:
static constexpr int ERROR_CODE_COLINEAR_CONSECUTIVE_WAYPOINTS{ 3104 };
};

} // namespace pilz_industrial_motion_planner
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*********************************************************************
* Software License Agreement (BSD License)
*
* Copyright (c) 2018 Pilz GmbH & Co. KG
* Copyright (c) 2025 Aiman Haidar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Pilz GmbH & Co. KG nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

#pragma once

#include <pilz_industrial_motion_planner/planning_context_loader.hpp>

#include <moveit/planning_interface/planning_interface.hpp>

namespace pilz_industrial_motion_planner
{
/**
* @brief Plugin that can generate instances of PlanningContextPolyline.
* Generates instances of PlanningContextPolyline.
*/
class PlanningContextLoaderPolyline : public PlanningContextLoader
{
public:
PlanningContextLoaderPolyline();
~PlanningContextLoaderPolyline() override;

/**
* @brief return a instance of
* pilz_industrial_motion_planner::PlanningContextPolyline
* @param planning_context returned context
* @param name
* @param group
* @return true on success, false otherwise
*/
bool loadContext(planning_interface::PlanningContextPtr& planning_context, const std::string& name,
const std::string& group) const override;
};

typedef std::shared_ptr<PlanningContextLoaderPolyline> PlanningContextLoaderPolylinePtr;
typedef std::shared_ptr<const PlanningContextLoaderPolyline> PlanningContextLoaderPolylineConstPtr;

} // namespace pilz_industrial_motion_planner
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*********************************************************************
* Software License Agreement (BSD License)
*
* Copyright (c) 2018 Pilz GmbH & Co. KG
* Copyright (c) 2025 Aiman Haidar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Pilz GmbH & Co. KG nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

#pragma once

#include <pilz_industrial_motion_planner/limits_container.hpp>

#include <rclcpp/rclcpp.hpp>

#include <moveit/planning_interface/planning_interface.hpp>
#include <moveit/planning_interface/planning_response.hpp>

#include <atomic>
#include <thread>

#include <pilz_industrial_motion_planner/planning_context_base.hpp>
#include <pilz_industrial_motion_planner/trajectory_generator_polyline.hpp>

namespace pilz_industrial_motion_planner
{
MOVEIT_CLASS_FORWARD(PlanningContext);

/**
* @brief PlanningContext for obtaining Polyline trajectories
*/
class PlanningContextPolyline : public pilz_industrial_motion_planner::PlanningContextBase<TrajectoryGeneratorPolyline>
{
public:
PlanningContextPolyline(const std::string& name, const std::string& group,
const moveit::core::RobotModelConstPtr& model,
const pilz_industrial_motion_planner::LimitsContainer& limits)
: pilz_industrial_motion_planner::PlanningContextBase<TrajectoryGeneratorPolyline>(name, group, model, limits)
{
}
};

} // namespace pilz_industrial_motion_planner
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class TrajectoryGenerator
std::string link_name;
Eigen::Isometry3d start_pose;
Eigen::Isometry3d goal_pose;
std::vector<Eigen::Isometry3d> waypoints;
std::map<std::string, double> start_joint_position;
std::map<std::string, double> goal_joint_position;
std::pair<std::string, Eigen::Vector3d> circ_path_point;
Expand All @@ -139,6 +140,11 @@ class TrajectoryGenerator
std::unique_ptr<KDL::VelocityProfile> cartesianTrapVelocityProfile(double max_velocity_scaling_factor,
double max_acceleration_scaling_factor,
const std::unique_ptr<KDL::Path>& path) const;
/**
* @brief Set the max cartesian speed from motion request
*/

void setMaxCartesianSpeed(const moveit_msgs::msg::MotionPlanRequest& req);

private:
virtual void cmdSpecificRequestValidation(const planning_interface::MotionPlanRequest& req) const;
Expand Down Expand Up @@ -270,6 +276,7 @@ class TrajectoryGenerator
protected:
const moveit::core::RobotModelConstPtr robot_model_;
const pilz_industrial_motion_planner::LimitsContainer planner_limits_;
double max_cartesian_speed_;
static constexpr double MIN_SCALING_FACTOR{ 0.0001 };
static constexpr double MAX_SCALING_FACTOR{ 1. };
static constexpr double VELOCITY_TOLERANCE{ 1e-8 };
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*********************************************************************
* Software License Agreement (BSD License)
*
* Copyright (c) 2018 Pilz GmbH & Co. KG
* Copyright (c) 2025 Aiman Haidar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Pilz GmbH & Co. KG nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

#pragma once

#include <eigen3/Eigen/Eigen>
#include <kdl/rotational_interpolation_sa.hpp>
#include <moveit/planning_scene/planning_scene.hpp>

#include <pilz_industrial_motion_planner/trajectory_generator.hpp>
#include <pilz_industrial_motion_planner/velocity_profile_atrap.hpp>

namespace pilz_industrial_motion_planner
{
// TODO date type of units

CREATE_MOVEIT_ERROR_CODE_EXCEPTION(LinTrajectoryConversionFailure, moveit_msgs::msg::MoveItErrorCodes::FAILURE);

CREATE_MOVEIT_ERROR_CODE_EXCEPTION(JointNumberMismatch, moveit_msgs::msg::MoveItErrorCodes::INVALID_GOAL_CONSTRAINTS);
CREATE_MOVEIT_ERROR_CODE_EXCEPTION(LinInverseForGoalIncalculable, moveit_msgs::msg::MoveItErrorCodes::NO_IK_SOLUTION);
CREATE_MOVEIT_ERROR_CODE_EXCEPTION(NoWaypointsSpecified, moveit_msgs::msg::MoveItErrorCodes::INVALID_MOTION_PLAN);
CREATE_MOVEIT_ERROR_CODE_EXCEPTION(ConsicutiveColinearWaypoints,
moveit_msgs::msg::MoveItErrorCodes::INVALID_MOTION_PLAN);

/**
* @brief This class implements a polyline trajectory generator in Cartesian
* space.
* The Cartesian trajetory are based on trapezoid velocity profile.
*/
class TrajectoryGeneratorPolyline : public TrajectoryGenerator
{
public:
/**
* @brief Constructor of Polyline Trajectory Generator
* @throw TrajectoryGeneratorInvalidLimitsException
* @param model: robot model
* @param planner_limits: limits in joint and Cartesian spaces
*/
TrajectoryGeneratorPolyline(const moveit::core::RobotModelConstPtr& robot_model,
const pilz_industrial_motion_planner::LimitsContainer& planner_limits,
const std::string& group_name);

private:
void cmdSpecificRequestValidation(const planning_interface::MotionPlanRequest& req) const override;

void extractMotionPlanInfo(const planning_scene::PlanningSceneConstPtr& scene,
const planning_interface::MotionPlanRequest& req, MotionPlanInfo& info) const final;

void plan(const planning_scene::PlanningSceneConstPtr& scene, const planning_interface::MotionPlanRequest& req,
const MotionPlanInfo& plan_info, double sampling_time,
trajectory_msgs::msg::JointTrajectory& joint_trajectory) override;

/**
* @brief construct a KDL::Path object for a Cartesian polyline path
* @param start_pose: start pose of the path
* @param waypoints: waypoints defining the path
* @param smoothness_level: smoothness level for blending the waypoints
* @return a unique pointer of the path object. null_ptr in case of an error.
*/
std::unique_ptr<KDL::Path> setPathPolyline(const Eigen::Affine3d& start_pose,
const std::vector<Eigen::Isometry3d>& waypoints,
double smoothness_level) const;
};

} // namespace pilz_industrial_motion_planner
Loading
Loading