37 #include <geometric_shapes/bodies.h> 38 #include <geometric_shapes/shapes.h> 40 #include <unordered_set> 44 #include <bio_ik/goal_types.h> 49 enum class Problem::GoalType
57 size_t Problem::addTipLink(
const moveit::core::LinkModel* link_model)
59 if(link_tip_indices[link_model->getLinkIndex()] < 0)
61 link_tip_indices[link_model->getLinkIndex()] = tip_link_indices.size();
62 tip_link_indices.push_back(link_model->getLinkIndex());
64 return link_tip_indices[link_model->getLinkIndex()];
68 : ros_params_initrd(false)
72 void Problem::initialize(moveit::core::RobotModelConstPtr robot_model,
const moveit::core::JointModelGroup* joint_model_group,
const IKParams& params,
const std::vector<const Goal*>& goals2,
const BioIKKinematicsQueryOptions* options)
74 if(robot_model != this->robot_model)
76 modelInfo = RobotInfo(robot_model);
77 #if (MOVEIT_FCL_VERSION < FCL_VERSION_CHECK(0, 6, 0)) 78 collision_links.clear();
79 collision_links.resize(robot_model->getLinkModelCount());
83 this->robot_model = robot_model;
84 this->joint_model_group = joint_model_group;
85 this->params = params;
87 if(!ros_params_initrd)
89 ros_params_initrd =
true;
92 dtwist = params.dtwist;
93 if(dpos < 0.0 || dpos >= FLT_MAX || !std::isfinite(dpos)) dpos = DBL_MAX;
94 if(drot < 0.0 || drot >= FLT_MAX || !std::isfinite(drot)) drot = DBL_MAX;
95 if(dtwist < 0.0 || dtwist >= FLT_MAX || !std::isfinite(dtwist)) dtwist = DBL_MAX;
98 link_tip_indices.clear();
99 link_tip_indices.resize(robot_model->getLinkModelCount(), -1);
100 tip_link_indices.clear();
102 active_variables.clear();
103 auto addActiveVariable = [
this, robot_model, joint_model_group, options](
const std::string& name) -> ssize_t {
106 auto& joint_name = robot_model->getJointOfVariable(name)->getName();
107 for(
auto& fixed_joint_name : options->fixed_joints)
109 if(fixed_joint_name == joint_name)
111 return (ssize_t)-1 - (ssize_t)robot_model->getVariableIndex(name);
115 for(
size_t i = 0; i < active_variables.size(); i++)
116 if(name == robot_model->getVariableNames()[active_variables[i]])
return i;
117 for(
auto& n : joint_model_group->getVariableNames())
121 active_variables.push_back(robot_model->getVariableIndex(name));
122 return active_variables.size() - 1;
125 ERROR(
"joint variable not found", name);
129 secondary_goals.clear();
130 for(
auto& goal : goals2)
134 goal_info.goal = goal;
136 goal->describe(goal_info.goal_context);
138 for(
auto& link_name : goal_info.goal_context.goal_link_names_)
140 auto* link_model = robot_model->getLinkModel(link_name);
141 if(!link_model) ERROR(
"link not found", link_name);
142 goal_info.goal_context.goal_link_indices_.push_back(addTipLink(link_model));
145 for(
auto& variable_name : goal_info.goal_context.goal_variable_names_)
147 goal_info.goal_context.goal_variable_indices_.push_back(addActiveVariable(variable_name));
150 goal_info.weight = goal_info.goal_context.goal_weight_;
151 goal_info.weight_sq = goal_info.weight * goal_info.weight;
153 goal_info.goal_type = GoalType::Unknown;
155 goal_info.frame = Frame::identity();
156 goal_info.tip_index = 0;
157 if(goal_info.goal_context.goal_link_indices_.size()) goal_info.tip_index = goal_info.goal_context.goal_link_indices_[0];
159 if(
auto* g = dynamic_cast<const PositionGoal*>(goal_info.goal))
161 goal_info.goal_type = GoalType::Position;
162 goal_info.frame.pos = g->getPosition();
165 if(
auto* g = dynamic_cast<const OrientationGoal*>(goal_info.goal))
167 goal_info.goal_type = GoalType::Orientation;
168 goal_info.frame.rot = g->getOrientation();
171 if(
auto* g = dynamic_cast<const PoseGoal*>(goal_info.goal))
173 goal_info.goal_type = GoalType::Pose;
174 goal_info.frame.pos = g->getPosition();
175 goal_info.frame.rot = g->getOrientation();
178 goal_info.goal_context.joint_model_group_ = joint_model_group;
179 goal_info.goal_context.initial_guess_ = initial_guess;
181 if(goal_info.goal_context.goal_secondary_)
182 secondary_goals.push_back(goal_info);
184 goals.push_back(goal_info);
192 joint_usage.resize(robot_model->getJointModelCount());
193 for(
auto& u : joint_usage)
195 for(
auto tip_index : tip_link_indices)
196 for(
auto* link_model = robot_model->getLinkModels()[tip_index]; link_model; link_model = link_model->getParentLinkModel())
197 joint_usage[link_model->getParentJointModel()->getJointIndex()] = 1;
199 for(
auto& fixed_joint_name : options->fixed_joints)
200 joint_usage[robot_model->getJointModel(fixed_joint_name)->getJointIndex()] = 0;
201 for(
auto* joint_model : joint_model_group->getActiveJointModels())
202 if(joint_usage[joint_model->getJointIndex()] && !joint_model->getMimic())
203 for(
auto& n : joint_model->getVariableNames())
204 addActiveVariable(n);
208 minimal_displacement_factors.resize(active_variables.size());
210 for(
auto ivar : active_variables)
211 s += modelInfo.getMaxVelocityRcp(ivar);
214 for(
size_t i = 0; i < active_variables.size(); i++)
216 auto ivar = active_variables[i];
217 minimal_displacement_factors[i] = modelInfo.getMaxVelocityRcp(ivar) / s;
222 for(
size_t i = 0; i < active_variables.size(); i++)
223 minimal_displacement_factors[i] = 1.0 / active_variables.size();
230 void Problem::initialize2()
232 for(
auto* gg : {&goals, &secondary_goals})
236 g.goal_context.problem_active_variables_ = active_variables;
237 g.goal_context.problem_tip_link_indices_ = tip_link_indices;
238 g.goal_context.velocity_weights_ = minimal_displacement_factors;
239 g.goal_context.robot_info_ = &modelInfo;
244 double Problem::computeGoalFitness(GoalInfo& goal_info,
const Frame* tip_frames,
const double* active_variable_positions)
246 goal_info.goal_context.tip_link_frames_ = tip_frames;
247 goal_info.goal_context.active_variable_positions_ = active_variable_positions;
248 return goal_info.goal->evaluate(goal_info.goal_context) * goal_info.weight_sq;
251 double Problem::computeGoalFitness(std::vector<GoalInfo>& goals,
const Frame* tip_frames,
const double* active_variable_positions)
254 for(
auto& goal : goals)
255 sum += computeGoalFitness(goal, tip_frames, active_variable_positions);
259 bool Problem::checkSolutionActiveVariables(
const std::vector<Frame>& tip_frames,
const double* active_variable_positions)
261 for(
auto& goal : goals)
263 const auto& fa = goal.frame;
264 const auto& fb = tip_frames[goal.tip_index];
266 switch(goal.goal_type)
269 case GoalType::Position:
273 double p_dist = (fb.pos - fa.pos).length();
274 if(!(p_dist <= dpos))
return false;
276 if(dtwist != DBL_MAX)
278 KDL::Frame fk_kdl, ik_kdl;
279 frameToKDL(fa, fk_kdl);
280 frameToKDL(fb, ik_kdl);
281 KDL::Twist kdl_diff(fk_kdl.M.Inverse() * KDL::diff(fk_kdl.p, ik_kdl.p), fk_kdl.M.Inverse() * KDL::diff(fk_kdl.M, ik_kdl.M));
282 if(!KDL::Equal(kdl_diff.vel, KDL::Twist::Zero().vel, dtwist))
return false;
287 case GoalType::Orientation:
291 double r_dist = fb.rot.angleShortestPath(fa.rot);
292 r_dist = r_dist * 180 / M_PI;
293 if(!(r_dist <= drot))
return false;
295 if(dtwist != DBL_MAX)
297 KDL::Frame fk_kdl, ik_kdl;
298 frameToKDL(fa, fk_kdl);
299 frameToKDL(fb, ik_kdl);
300 KDL::Twist kdl_diff(fk_kdl.M.Inverse() * KDL::diff(fk_kdl.p, ik_kdl.p), fk_kdl.M.Inverse() * KDL::diff(fk_kdl.M, ik_kdl.M));
301 if(!KDL::Equal(kdl_diff.rot, KDL::Twist::Zero().rot, dtwist))
return false;
308 if(dpos != DBL_MAX || drot != DBL_MAX)
310 double p_dist = (fb.pos - fa.pos).length();
311 double r_dist = fb.rot.angleShortestPath(fa.rot);
312 r_dist = r_dist * 180 / M_PI;
313 if(!(p_dist <= dpos))
return false;
314 if(!(r_dist <= drot))
return false;
316 if(dtwist != DBL_MAX)
318 KDL::Frame fk_kdl, ik_kdl;
319 frameToKDL(fa, fk_kdl);
320 frameToKDL(fb, ik_kdl);
321 KDL::Twist kdl_diff(fk_kdl.M.Inverse() * KDL::diff(fk_kdl.p, ik_kdl.p), fk_kdl.M.Inverse() * KDL::diff(fk_kdl.M, ik_kdl.M));
322 if(!KDL::Equal(kdl_diff, KDL::Twist::Zero(), dtwist))
return false;
329 double dmax = DBL_MAX;
330 dmax = std::fmin(dmax, dpos);
331 dmax = std::fmin(dmax, dtwist);
332 double d = computeGoalFitness(goal, tip_frames.data(), active_variable_positions);
333 if(!(d < dmax * dmax))
return false;