40 #include <moveit_msgs/MotionPlanRequest.h>
42 #include <trajopt_sco/sco_common.hpp>
43 #include <trajopt_sco/optimizers.hpp>
44 #include <trajopt_sco/solver_interface.hpp>
46 #include <trajopt/trajectory_costs.hpp>
49 #include <rosparam_shortcuts/rosparam_shortcuts.h>
53 #include <Eigen/Geometry>
54 #include <unordered_map>
72 moveit_msgs::MotionPlanDetailedResponse& res)
74 ROS_INFO(
" ======================================= From trajopt_interface, solve is called");
79 ROS_ERROR_STREAM_NAMED(
name_,
"No planning scene initialized.");
80 res.error_code.val = moveit_msgs::MoveItErrorCodes::FAILURE;
84 ROS_INFO(
" ======================================= Extract current state information");
85 ros::WallTime start_time = ros::WallTime::now();
86 moveit::core::RobotModelConstPtr robot_model =
planning_scene->getRobotModel();
87 bool robot_model_ok =
static_cast<bool>(robot_model);
89 ROS_ERROR_STREAM_NAMED(
name_,
"robot model is not loaded properly");
90 auto current_state = std::make_shared<moveit::core::RobotState>(robot_model);
93 if (joint_model_group ==
nullptr)
94 ROS_ERROR_STREAM_NAMED(
name_,
"joint model group is empty");
96 int dof = group_joint_names.size();
97 std::vector<double> current_joint_values;
98 current_state->copyJointGroupPositions(joint_model_group, current_joint_values);
101 ROS_INFO(
" ======================================= Extract start state information");
105 if (start_joint_values.empty())
107 ROS_ERROR_STREAM_NAMED(
name_,
"Start_state is empty");
108 res.error_code.val = moveit_msgs::MoveItErrorCodes::INVALID_ROBOT_STATE;
114 ROS_ERROR_STREAM_NAMED(
name_,
"Start state violates joint limits");
115 res.error_code.val = moveit_msgs::MoveItErrorCodes::INVALID_ROBOT_STATE;
119 ROS_INFO(
" ======================================= Create ProblemInfo");
124 ROS_INFO(
" ======================================= Populate init info, hard-coded");
128 Eigen::VectorXd current_joint_values_eigen(dof);
129 for (
int joint_index = 0; joint_index < dof; ++joint_index)
131 current_joint_values_eigen(joint_index) = current_joint_values[joint_index];
143 ROS_INFO(
" ======================================= Create Constraints");
144 if (req.goal_constraints.empty())
146 ROS_ERROR_STREAM_NAMED(
"trajopt_planner",
"No goal constraints specified!");
147 res.error_code.val = moveit_msgs::MoveItErrorCodes::INVALID_GOAL_CONSTRAINTS;
151 ROS_INFO(
" ======================================= Cartesian Constraints");
152 if (!req.goal_constraints[0].position_constraints.empty() && !req.goal_constraints[0].orientation_constraints.empty())
154 CartPoseTermInfoPtr cart_goal_pos = std::make_shared<CartPoseTermInfo>();
160 problem_info.
cnt_infos.push_back(cart_goal_pos);
162 else if (req.goal_constraints[0].position_constraints.empty() &&
163 !req.goal_constraints[0].orientation_constraints.empty())
165 ROS_ERROR_STREAM_NAMED(
"trajopt_planner",
"position constraint is not defined");
166 res.error_code.val = moveit_msgs::MoveItErrorCodes::INVALID_GOAL_CONSTRAINTS;
169 else if (!req.goal_constraints[0].orientation_constraints.empty() &&
170 req.goal_constraints[0].orientation_constraints.empty())
172 ROS_ERROR_STREAM_NAMED(
"trajopt_planner",
"orientation constraint is not defined");
173 res.error_code.val = moveit_msgs::MoveItErrorCodes::INVALID_GOAL_CONSTRAINTS;
177 ROS_INFO(
" ======================================= Constraints from request goal_constraints");
178 for (
auto goal_cnt : req.goal_constraints)
180 JointPoseTermInfoPtr joint_pos_term = std::make_shared<JointPoseTermInfo>();
184 trajopt::DblVec joint_goal_constraints;
185 for (
const moveit_msgs::JointConstraint& joint_goal_constraint : goal_cnt.joint_constraints)
187 joint_goal_constraints.push_back(joint_goal_constraint.position);
189 joint_pos_term->targets = joint_goal_constraints;
190 problem_info.
cnt_infos.push_back(joint_pos_term);
193 ROS_INFO(
" ======================================= Constraints from request start_state");
195 auto joint_start_pos = std::make_shared<JointPoseTermInfo>();
197 joint_start_pos->targets = start_joint_values;
199 problem_info.
cnt_infos.push_back(joint_start_pos);
201 ROS_INFO(
" ======================================= Velocity Constraints, hard-coded");
203 auto joint_vel = std::make_shared<JointVelTermInfo>();
205 joint_vel->coeffs = std::vector<double>(dof, 5.0);
206 joint_vel->targets = std::vector<double>(dof, 0.0);
207 joint_vel->first_step = 0;
209 joint_vel->name =
"joint_vel";
213 ROS_INFO(
" ======================================= Visibility Constraints");
214 if (!req.goal_constraints[0].visibility_constraints.empty())
219 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.improve_ratio_threshold: " <<
params_.improve_ratio_threshold);
220 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.min_trust_box_size: " <<
params_.min_trust_box_size);
221 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.min_approx_improve: " <<
params_.min_approx_improve);
222 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.params_.min_approx_improve_frac: " <<
params_.min_approx_improve_frac);
223 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.max_iter: " <<
params_.max_iter);
224 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.trust_shrink_ratio: " <<
params_.trust_shrink_ratio);
225 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.trust_expand_ratio: " <<
params_.trust_expand_ratio);
226 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.cnt_tolerance: " <<
params_.cnt_tolerance);
227 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.max_merit_coeff_increases: " <<
params_.max_merit_coeff_increases);
228 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.merit_coeff_increase_ratio: " <<
params_.merit_coeff_increase_ratio);
229 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.max_time: " <<
params_.max_time);
230 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.merit_error_coeff: " <<
params_.merit_error_coeff);
231 ROS_DEBUG_STREAM_NAMED(
name_,
"trajopt_param.trust_box_size: " <<
params_.trust_box_size);
239 std::string problem_info_type;
243 problem_info_type =
"STATIONARY";
246 problem_info_type =
"JOINT_INTERPOLATED";
249 problem_info_type =
"GIVEN_TRAJ";
252 ROS_DEBUG_STREAM_NAMED(
name_,
"problem_info.basic_info.type: " << problem_info_type);
253 ROS_DEBUG_STREAM_NAMED(
name_,
"problem_info.basic_info.dt: " << problem_info.
init_info.
dt);
255 ROS_INFO(
" ======================================= Construct problem");
259 ROS_INFO_STREAM_NAMED(
"num_constraints",
trajopt_problem_->getNumConstraints());
261 ROS_INFO(
" ======================================= TrajOpt Optimization");
270 opt.addCallback(callback);
274 ros::WallTime create_time = ros::WallTime::now();
277 ROS_INFO(
" ======================================= TrajOpt Solution");
281 ROS_INFO_STREAM_NAMED(
"num_rows", opt_solution.rows());
282 ROS_INFO_STREAM_NAMED(
"num_cols", opt_solution.cols());
284 res.trajectory.resize(1);
285 res.trajectory[0].joint_trajectory.joint_names = group_joint_names;
286 res.trajectory[0].joint_trajectory.header = req.start_state.joint_state.header;
289 res.trajectory[0].joint_trajectory.points.resize(opt_solution.rows());
290 for (
int i = 0; i < opt_solution.rows(); ++i)
292 res.trajectory[0].joint_trajectory.points[i].positions.resize(opt_solution.cols());
293 for (
size_t j = 0; j < opt_solution.cols(); ++j)
295 res.trajectory[0].joint_trajectory.points[i].positions[j] = opt_solution(i, j);
298 res.trajectory[0].joint_trajectory.points[i].time_from_start = ros::Duration(0.0);
301 res.error_code.val = moveit_msgs::MoveItErrorCodes::SUCCESS;
302 res.processing_time.push_back((ros::WallTime::now() - start_time).toSec());
304 ROS_INFO(
" ======================================= check if final state is within goal tolerances");
307 last_state.
setJointGroupPositions(req.group_name, res.trajectory[0].joint_trajectory.points.back().positions);
309 for (
int jn = 0; jn < res.trajectory[0].joint_trajectory.points.back().positions.size(); ++jn)
311 ROS_INFO_STREAM_NAMED(
"joint_value", res.trajectory[0].joint_trajectory.points.back().positions[jn]
312 <<
" " << req.goal_constraints.back().joint_constraints[jn].position);
315 bool constraints_are_ok =
true;
316 int joint_cnt_index = 0;
317 for (
const moveit_msgs::JointConstraint& constraint : req.goal_constraints.back().joint_constraints)
319 ROS_INFO(
"index %i: jc.configure(constraint)=> %d, jc.decide(last_state).satisfied=> %d, tolerance %f",
321 constraint.tolerance_above);
322 constraints_are_ok = constraints_are_ok and joint_cnt.
configure(constraint);
323 constraints_are_ok = constraints_are_ok and joint_cnt.
decide(last_state).
satisfied;
324 if (not constraints_are_ok)
326 ROS_ERROR_STREAM_NAMED(
"trajopt_planner",
"Goal constraints are violated: " << constraint.joint_name);
327 res.error_code.val = moveit_msgs::MoveItErrorCodes::GOAL_CONSTRAINTS_VIOLATED;
330 joint_cnt_index = joint_cnt_index + 1;
333 ROS_INFO(
" ==================================== Response");
334 res.trajectory_start = req.start_state;
336 ROS_INFO(
" ==================================== Debug Response");
337 ROS_INFO_STREAM_NAMED(
"group_name", res.group_name);
338 ROS_INFO_STREAM_NAMED(
"start_traj_name_size", res.trajectory_start.joint_state.name.size());
339 ROS_INFO_STREAM_NAMED(
"start_traj_position_size", res.trajectory_start.joint_state.position.size());
340 ROS_INFO_STREAM_NAMED(
"traj_name_size", res.trajectory[0].joint_trajectory.joint_names.size());
341 ROS_INFO_STREAM_NAMED(
"traj_point_size", res.trajectory[0].joint_trajectory.points.size());
347 sco::BasicTrustRegionSQPParameters params;
353 nh_.param(
"trajopt_param/improve_ratio_threshold", params.improve_ratio_threshold, 0.25);
354 nh_.param(
"trajopt_param/min_trust_box_size", params.min_trust_box_size, 1e-4);
355 nh_.param(
"trajopt_param/min_approx_improve", params.min_approx_improve, 1e-4);
356 nh_.param(
"trajopt_param/min_approx_improve_frac", params.min_approx_improve_frac, -
static_cast<double>(INFINITY));
357 nh_.param(
"trajopt_param/max_iter", params.max_iter, 100.0);
358 nh_.param(
"trajopt_param/trust_shrink_ratio", params.trust_shrink_ratio, 0.1);
360 nh_.param(
"trajopt_param/trust_expand_ratio", params.trust_expand_ratio, 1.5);
361 nh_.param(
"trajopt_param/cnt_tolerance", params.cnt_tolerance, 1e-4);
362 nh_.param(
"trajopt_param/max_merit_coeff_increases", params.max_merit_coeff_increases, 5.0);
363 nh_.param(
"trajopt_param/merit_coeff_increase_ratio", params.merit_coeff_increase_ratio, 10.0);
364 nh_.param(
"trajopt_param/max_time", params.max_time,
static_cast<double>(INFINITY));
365 nh_.param(
"trajopt_param/merit_error_coeff", params.merit_error_coeff, 10.0);
366 nh_.param(
"trajopt_param/trust_box_size", params.trust_box_size, 1e-1);
376 int convex_solver_index;
377 nh_.param(
"problem_info/basic_info/convex_solver", convex_solver_index, 1);
378 switch (convex_solver_index)
397 nh_.param(
"problem_info/init_info/dt", problem_info.
init_info.
dt, 0.5);
399 nh_.param(
"problem_info/init_info/type", type_index, 1);
417 std::string term_type_address =
"joint_pos_term_info/" +
name +
"/term_type";
418 nh_.param(term_type_address, term_type_index, 1);
420 switch (term_type_index)
433 nh_.getParam(
"joint_pos_term_info/" +
name +
"/first_timestep", jp->first_step);
434 nh_.getParam(
"joint_pos_term_info/" +
name +
"/last_timestep", jp->last_step);
435 nh_.getParam(
"joint_pos_term_info/" +
name +
"/name", jp->name);
439 const std::vector<std::string>& group_joint_names)
441 std::unordered_map<std::string, double> all_joints;
442 trajopt::DblVec start_joint_vals;
444 for (
int joint_index = 0; joint_index < req.start_state.joint_state.position.size(); ++joint_index)
446 all_joints[req.start_state.joint_state.name[joint_index]] = req.start_state.joint_state.position[joint_index];
449 for (
auto joint_name : group_joint_names)
451 ROS_INFO(
" joint position from start state, name: %s, value: %f", joint_name.c_str(), all_joints[joint_name]);
452 start_joint_vals.push_back(all_joints[joint_name]);
455 return start_joint_vals;
Class for handling single DOF joint constraints.
ConstraintEvaluationResult decide(const moveit::core::RobotState &state, bool verbose=false) const override
Decide whether the constraint is satisfied in the indicated state.
bool configure(const moveit_msgs::msg::JointConstraint &jc)
Configure the constraint based on a moveit_msgs::msg::JointConstraint.
bool satisfiesPositionBounds(const double *state, double margin=0.0) const
const std::vector< std::string > & getActiveJointModelNames() const
Get the names of the active joints in this group. These are the names of the joints returned by getJo...
Representation of a robot's state. This includes position, velocity, acceleration and effort.
void setJointGroupPositions(const std::string &joint_group_name, const double *gstate)
Given positions for the variables that make up a group, in the order found in the group (including va...
void setDefaultTrajOPtParams()
void setProblemInfoParam(ProblemInfo &problem_info)
TrajOptInterface(const ros::NodeHandle &nh=ros::NodeHandle("~"))
bool solve(const planning_scene::PlanningSceneConstPtr &planning_scene, const planning_interface::MotionPlanRequest &req, moveit_msgs::MotionPlanDetailedResponse &res)
sco::BasicTrustRegionSQPParameters params_
The ROS node handle.
void setJointPoseTermInfoParams(JointPoseTermInfoPtr &jp, std::string name)
TrajOptProblemPtr trajopt_problem_
void setTrajOptParams(sco::BasicTrustRegionSQPParameters ¶m)
Configure everything using the param server.
trajopt::DblVec extractStartJointValues(const planning_interface::MotionPlanRequest &req, const std::vector< std::string > &group_joint_names)
std::vector< sco::Optimizer::Callback > optimizer_callbacks_
moveit_msgs::msg::MotionPlanRequest MotionPlanRequest
This namespace includes the central class for representing planning contexts.
void callBackFunc(sco::OptProb *opt_prob, sco::OptResults &opt_res)
TrajOptProblemPtr ConstructProblem(const ProblemInfo &)
bool satisfied
Whether or not the constraint or constraints were satisfied.
int n_steps
Number of time steps (rows) in the optimization matrix.
double dt_upper_lim
The upper limit of 1/dt values allowed in the optimization.
double dt_lower_lim
The lower limit of 1/dt values allowed in the optimization.
bool use_time
If true, the last column in the optimization matrix will be 1/dt.
bool start_fixed
If true, first time step is fixed with a joint level constraint If this is false, the starting point ...
sco::ModelType convex_solver
trajopt::TrajArray data
Data used during initialization. Use depends on the initialization selected. This data will be used t...
Type type
Specifies the type of initialization to use.
double dt
Default value the final column of the optimization is initialized too if time is being used.
std::vector< TermInfoPtr > cnt_infos
std::vector< TermInfoPtr > cost_infos