42 #include <stomp/stomp.h>
50 #include <stomp_moveit_parameters.hpp>
62 const robot_trajectory::RobotTrajectoryPtr& input_trajectory,
63 robot_trajectory::RobotTrajectoryPtr& output_trajectory)
65 Eigen::MatrixXd waypoints;
66 const auto& joints =
group->getActiveJointModels();
68 if (!input_trajectory || input_trajectory->empty())
79 output_trajectory = std::make_shared<robot_trajectory::RobotTrajectory>(start_state.
getRobotModel(),
group);
88 const moveit::core::RobotModelConstPtr& robot_model,
89 robot_trajectory::RobotTrajectoryPtr& seed)
91 if (req.trajectory_constraints.constraints.empty())
96 const auto* joint_group = robot_model->getJointModelGroup(req.group_name);
97 const auto& names = joint_group->getActiveJointModelNames();
98 const auto dof = names.size();
100 trajectory_msgs::msg::JointTrajectory seed_traj;
101 const auto& constraints = req.trajectory_constraints.constraints;
103 for (
size_t i = 0; i < constraints.size(); ++i)
105 auto n = constraints[i].joint_constraints.size();
108 RCLCPP_WARN(LOGGER,
"Seed trajectory index %lu does not have %lu constraints (has %lu instead).", i, dof, n);
112 trajectory_msgs::msg::JointTrajectoryPoint joint_pt;
114 for (
size_t j = 0; j < constraints[i].joint_constraints.size(); ++j)
116 const auto& c = constraints[i].joint_constraints[j];
117 if (c.joint_name != names[j])
119 RCLCPP_WARN(LOGGER,
"Seed trajectory (index %lu, joint %lu) joint name '%s' does not match expected name '%s'",
120 i, j, c.joint_name.c_str(), names[j].c_str());
123 joint_pt.positions.push_back(c.position);
126 seed_traj.points.push_back(joint_pt);
128 seed_traj.joint_names = names;
132 seed = std::make_shared<robot_trajectory::RobotTrajectory>(robot_model, joint_group);
133 seed->setRobotTrajectoryMsg(robot_state, seed_traj);
135 return !seed->empty();
141 const size_t num_timesteps = config.num_timesteps;
155 if (!constraints.
empty())
167 const std::vector<double> stddev(
group->getActiveJointModels().size(), 0.1);
171 auto iteration_callback_fn =
173 auto done_callback_fn =
177 stomp::TaskPtr task =
178 std::make_shared<ComposableTask>(noise_generator_fn, cost_fn, filter_fn, iteration_callback_fn, done_callback_fn);
183 stomp::StompConfiguration
getStompConfig(
const stomp_moveit::Params& params,
size_t num_dimensions)
185 stomp::StompConfiguration config;
186 config.num_dimensions = num_dimensions;
188 config.initialization_method = stomp::TrajectoryInitializations::LINEAR_INTERPOLATION;
189 config.num_iterations = params.num_iterations;
190 config.num_iterations_after_valid = params.num_iterations_after_valid;
191 config.num_timesteps = params.num_timesteps;
192 config.delta_t = params.delta_t;
193 config.exponentiated_cost_sensitivity = params.exponentiated_cost_sensitivity;
194 config.num_rollouts = params.num_rollouts;
195 config.max_rollouts = params.max_rollouts;
196 config.control_cost_weight = params.control_cost_weight;
202 const stomp_moveit::Params& params)
210 auto time_start = std::chrono::steady_clock::now();
214 res.
error_code.val = moveit_msgs::msg::MoveItErrorCodes::SUCCESS;
222 if (!goal_sampler || !goal_sampler->sample(goal_state))
224 res.
error_code.val = moveit_msgs::msg::MoveItErrorCodes::INVALID_GOAL_CONSTRAINTS;
231 robot_trajectory::RobotTrajectoryPtr input_trajectory;
234 config.num_timesteps = input_trajectory->size();
237 stomp_ = std::make_shared<stomp::Stomp>(config, task);
239 std::condition_variable cv;
241 bool finished =
false;
242 auto timeout_future = std::async(std::launch::async, [&,
stomp = stomp_]() {
243 std::unique_lock<std::mutex> lock(cv_mutex);
244 cv.wait_for(lock, std::chrono::duration<double>(req.allowed_planning_time), [&finished] { return finished; });
256 timeout_future.valid() && timeout_future.wait_for(std::chrono::nanoseconds(1)) == std::future_status::ready;
258 timed_out ? moveit_msgs::msg::MoveItErrorCodes::TIMED_OUT : moveit_msgs::msg::MoveItErrorCodes::PLANNING_FAILED;
262 std::unique_lock<std::mutex> lock(cv_mutex);
268 std::chrono::duration<double> elapsed_seconds = std::chrono::steady_clock::now() - time_start;
271 return res.
error_code.val == moveit_msgs::msg::MoveItErrorCodes::SUCCESS;
278 "StompPlanningContext::solve(planning_interface::MotionPlanDetailedResponse&) is not implemented!");
288 return stomp->cancel();
299 const std::shared_ptr<rclcpp::Publisher<visualization_msgs::msg::MarkerArray>>& path_publisher)
301 path_publisher_ = path_publisher;
306 return path_publisher_;
This class assists in the generation of a ConstraintSampler for a particular group from a moveit_msgs...
ConstraintSamplerPtr selectSampler(const planning_scene::PlanningSceneConstPtr &scene, const std::string &group_name, const moveit_msgs::msg::Constraints &constr) const
Selects among the potential sampler allocators.
A class that contains many different constraints, and can check RobotState *versus the full set....
const moveit_msgs::msg::Constraints & getAllConstraints() const
Get all constraints in the set.
bool empty() const
Returns whether or not there are any constraints in the set.
bool add(const moveit_msgs::msg::Constraints &c, const moveit::core::Transforms &tf)
Add all known constraints.
Representation of a robot's state. This includes position, velocity, acceleration and effort.
const RobotModelConstPtr & getRobotModel() const
Get the robot model this state is constructed for.
Representation of a particular planning context – the planning scene and the request are known,...
MotionPlanRequest request_
The planning request for this context.
const std::string & getGroupName() const
Get the name of the group this planning context is for.
const MotionPlanRequest & getMotionPlanRequest() const
Get the motion plan request associated to this planning context.
const planning_scene::PlanningSceneConstPtr & getPlanningScene() const
Get the planning scene associated to this planning context.
void clear() override
Clear the data structures used by the planner.
std::shared_ptr< rclcpp::Publisher< visualization_msgs::msg::MarkerArray > > getPathPublisher()
void setPathPublisher(const std::shared_ptr< rclcpp::Publisher< visualization_msgs::msg::MarkerArray >> &path_publisher)
bool terminate() override
If solve() is running, terminate the computation. Return false if termination not possible....
StompPlanningContext(const std::string &name, const std::string &group_name, const stomp_moveit::Params ¶ms)
bool solve(planning_interface::MotionPlanResponse &res) override
Solve the motion planning problem and store the result in res. This function should not clear data st...
MoveIt-based cost functions that can be passed to STOMP via a ComposableTask.
Filter functions that can be passed to STOMP via a ComposableTask.
bool robotStateMsgToRobotState(const Transforms &tf, const moveit_msgs::msg::RobotState &robot_state, RobotState &state, bool copy_attached_bodies=true)
Convert a robot state msg (with accompanying extra transforms) to a MoveIt robot state.
rclcpp::Logger get_logger()
This namespace includes the base class for MoveIt planners.
moveit_msgs::msg::MotionPlanRequest MotionPlanRequest
This namespace includes the central class for representing planning contexts.
CostFn getConstraintsCostFunction(const std::shared_ptr< const planning_scene::PlanningScene > &planning_scene, const moveit::core::JointModelGroup *group, const moveit_msgs::msg::Constraints &constraints_msg, double cost_scale)
CostFn sum(const std::vector< CostFn > &cost_functions)
CostFn getCollisionCostFunction(const std::shared_ptr< const planning_scene::PlanningScene > &planning_scene, const moveit::core::JointModelGroup *group, double collision_penalty)
FilterFn chain(const std::vector< FilterFn > &filter_functions)
FilterFn enforcePositionBounds(const moveit::core::JointModelGroup *group)
FilterFn simpleSmoothingMatrix(size_t num_timesteps)
NoiseGeneratorFn getNormalDistributionGenerator(size_t num_timesteps, const std::vector< double > &stddev)
PostIterationFn getIterationPathPublisher(const rclcpp::Publisher< visualization_msgs::msg::MarkerArray >::SharedPtr &marker_publisher, const std::shared_ptr< const planning_scene::PlanningScene > &planning_scene, const moveit::core::JointModelGroup *group)
Get post iteration function that publishes the EE path of the generated trajectory.
DoneFn getSuccessTrajectoryPublisher(const rclcpp::Publisher< visualization_msgs::msg::MarkerArray >::SharedPtr &marker_publisher, const std::shared_ptr< const planning_scene::PlanningScene > &planning_scene, const moveit::core::JointModelGroup *group)
Get Done function that publishes the EE path of the generated trajectory.
Eigen::MatrixXd robotTrajectoryToMatrix(const robot_trajectory::RobotTrajectory &trajectory)
void fillRobotTrajectory(const Eigen::MatrixXd &trajectory_values, const moveit::core::RobotState &reference_state, robot_trajectory::RobotTrajectory &trajectory)
std::vector< double > getPositions(const moveit::core::RobotState &state, const Joints &joints)
bool extractSeedTrajectory(const planning_interface::MotionPlanRequest &req, const moveit::core::RobotModelConstPtr &robot_model, robot_trajectory::RobotTrajectoryPtr &seed)
bool solveWithStomp(const std::shared_ptr< stomp::Stomp > &stomp, const moveit::core::RobotState &start_state, const moveit::core::RobotState &goal_state, const moveit::core::JointModelGroup *group, const robot_trajectory::RobotTrajectoryPtr &input_trajectory, robot_trajectory::RobotTrajectoryPtr &output_trajectory)
std::function< bool(const Eigen::MatrixXd &values, Eigen::VectorXd &costs, bool &validity)> CostFn
stomp::StompConfiguration getStompConfig(const stomp_moveit::Params ¶ms, size_t num_dimensions)
stomp::TaskPtr createStompTask(const stomp::StompConfiguration &config, StompPlanningContext &context)
Noise generator functions for randomizing trajectories in STOMP via a ComposableTask.
Planning Context implementation for STOMP.
A STOMP task definition that allows injecting custom functions for planning.
Response to a planning query.
moveit::core::MoveItErrorCode error_code
robot_trajectory::RobotTrajectoryPtr trajectory
: Helper functions for visualizing trajectory markers for STOMP planning iterations.