33 #include <exotica_core/task_initializer.h> 39 EndPoseProblem::EndPoseProblem()
44 EndPoseProblem::~EndPoseProblem() =
default;
46 Eigen::MatrixXd EndPoseProblem::GetBounds()
const 48 return scene_->GetKinematicTree().GetJointLimits();
51 void EndPoseProblem::Instantiate(
const EndPoseProblemInitializer& init)
54 num_tasks = tasks_.size();
57 for (
int i = 0; i < num_tasks; ++i)
60 length_Phi += tasks_[i]->length;
61 length_jacobian += tasks_[i]->length_jacobian;
63 Phi.SetZero(length_Phi);
64 W = Eigen::MatrixXd::Identity(N, N);
65 if (init.W.rows() > 0)
67 if (init.W.rows() == N)
69 W.diagonal() = init.W;
73 ThrowNamed(
"W dimension mismatch! Expected " << N <<
", got " << init.W.rows());
76 if (flags_ &
KIN_J) jacobian = Eigen::MatrixXd(length_jacobian, N);
77 if (flags_ &
KIN_H) hessian.setConstant(length_jacobian, Eigen::MatrixXd::Zero(N, N));
79 if (init.LowerBound.rows() == N)
81 scene_->GetKinematicTree().SetJointLimitsLower(init.LowerBound);
83 else if (init.LowerBound.rows() != 0)
85 ThrowNamed(
"Lower bound size incorrect! Expected " << N <<
" got " << init.LowerBound.rows());
87 if (init.UpperBound.rows() == N)
89 scene_->GetKinematicTree().SetJointLimitsUpper(init.UpperBound);
91 else if (init.UpperBound.rows() != 0)
93 ThrowNamed(
"Lower bound size incorrect! Expected " << N <<
" got " << init.UpperBound.rows());
96 use_bounds = init.UseBounds;
99 cost.Initialize(init.Cost, shared_from_this(), dummy);
100 inequality.Initialize(init.Inequality, shared_from_this(), dummy);
101 equality.Initialize(init.Equality, shared_from_this(), dummy);
102 ApplyStartState(
false);
106 void EndPoseProblem::PreUpdate()
108 PlanningProblem::PreUpdate();
109 for (
int i = 0; i < tasks_.size(); ++i) tasks_[i]->is_used =
false;
111 inequality.UpdateS();
115 double EndPoseProblem::GetScalarCost()
117 return cost.ydiff.transpose() * cost.S * cost.ydiff;
120 Eigen::RowVectorXd EndPoseProblem::GetScalarJacobian()
122 return cost.jacobian.transpose() * cost.S * cost.ydiff * 2.0;
125 double EndPoseProblem::GetScalarTaskCost(
const std::string& task_name)
const 127 for (
int i = 0; i < cost.indexing.size(); ++i)
129 if (cost.tasks[i]->GetObjectName() == task_name)
131 return cost.ydiff.segment(cost.indexing[i].start, cost.indexing[i].length).transpose() * cost.rho(cost.indexing[i].id) * cost.ydiff.segment(cost.indexing[i].start, cost.indexing[i].length);
134 ThrowPretty(
"Cannot get scalar task cost. Task Map '" << task_name <<
"' does not exist.");
137 Eigen::VectorXd EndPoseProblem::GetEquality()
139 return equality.S * equality.ydiff;
142 Eigen::MatrixXd EndPoseProblem::GetEqualityJacobian()
144 return equality.S * equality.jacobian;
147 Eigen::VectorXd EndPoseProblem::GetInequality()
149 return inequality.S * inequality.ydiff;
152 Eigen::MatrixXd EndPoseProblem::GetInequalityJacobian()
154 return inequality.S * inequality.jacobian;
159 scene_->Update(x, t_start);
160 Phi.SetZero(length_Phi);
161 if (flags_ &
KIN_J) jacobian.setZero();
163 for (
int i = 0; i < length_jacobian; ++i) hessian(i).setZero();
164 for (
int i = 0; i < tasks_.size(); ++i)
166 if (tasks_[i]->is_used)
171 Phi.data.segment(tasks_[i]->start, tasks_[i]->length),
172 jacobian.middleRows(tasks_[i]->start_jacobian, tasks_[i]->length_jacobian),
173 hessian.segment(tasks_[i]->start_jacobian, tasks_[i]->length_jacobian));
175 else if (flags_ & KIN_J)
178 Phi.data.segment(tasks_[i]->start, tasks_[i]->length),
179 Eigen::MatrixXdRef(jacobian.middleRows(tasks_[i]->start_jacobian, tasks_[i]->length_jacobian))
184 tasks_[i]->Update(x, Phi.data.segment(tasks_[i]->start, tasks_[i]->length));
190 cost.Update(Phi, jacobian, hessian);
191 inequality.Update(Phi, jacobian, hessian);
192 equality.Update(Phi, jacobian, hessian);
194 else if (flags_ & KIN_J)
196 cost.Update(Phi, jacobian);
197 inequality.Update(Phi, jacobian);
198 equality.Update(Phi, jacobian);
203 inequality.Update(Phi);
204 equality.Update(Phi);
206 ++number_of_problem_updates_;
211 for (
int i = 0; i < cost.indexing.size(); ++i)
213 if (cost.tasks[i]->GetObjectName() == task_name)
215 if (goal.rows() != cost.indexing[i].length)
ThrowPretty(
"Expected length of " << cost.indexing[i].length <<
" and got " << goal.rows());
216 cost.y.data.segment(cost.indexing[i].start, cost.indexing[i].length) = goal;
220 ThrowPretty(
"Cannot set Goal. Task Map '" << task_name <<
"' does not exist.");
223 void EndPoseProblem::SetRho(
const std::string& task_name,
const double& rho)
225 for (
int i = 0; i < cost.indexing.size(); ++i)
227 if (cost.tasks[i]->GetObjectName() == task_name)
229 cost.rho(cost.indexing[i].id) = rho;
234 ThrowPretty(
"Cannot set rho. Task Map '" << task_name <<
"' does not exist.");
237 Eigen::VectorXd EndPoseProblem::GetGoal(
const std::string& task_name)
239 for (
int i = 0; i < cost.indexing.size(); ++i)
241 if (cost.tasks[i]->GetObjectName() == task_name)
243 return cost.y.data.segment(cost.indexing[i].start, cost.indexing[i].length);
246 ThrowPretty(
"Cannot get Goal. Task Map '" << task_name <<
"' does not exist.");
249 double EndPoseProblem::GetRho(
const std::string& task_name)
251 for (
int i = 0; i < cost.indexing.size(); ++i)
253 if (cost.tasks[i]->GetObjectName() == task_name)
255 return cost.rho(cost.indexing[i].id);
258 ThrowPretty(
"Cannot get rho. Task Map '" << task_name <<
"' does not exist.");
263 for (
int i = 0; i < equality.indexing.size(); ++i)
265 if (equality.tasks[i]->GetObjectName() == task_name)
267 if (goal.rows() != equality.indexing[i].length)
ThrowPretty(
"Expected length of " << equality.indexing[i].length <<
" and got " << goal.rows());
268 equality.y.data.segment(equality.indexing[i].start, equality.indexing[i].length) = goal;
272 ThrowPretty(
"Cannot set Goal. Task Map '" << task_name <<
"' does not exist.");
275 void EndPoseProblem::SetRhoEQ(
const std::string& task_name,
const double& rho)
277 for (
int i = 0; i < equality.indexing.size(); ++i)
279 if (equality.tasks[i]->GetObjectName() == task_name)
281 equality.rho(equality.indexing[i].id) = rho;
286 ThrowPretty(
"Cannot set rho. Task Map '" << task_name <<
"' does not exist.");
289 Eigen::VectorXd EndPoseProblem::GetGoalEQ(
const std::string& task_name)
291 for (
int i = 0; i < equality.indexing.size(); ++i)
293 if (equality.tasks[i]->GetObjectName() == task_name)
295 return equality.y.data.segment(equality.indexing[i].start, equality.indexing[i].length);
298 ThrowPretty(
"Cannot get Goal. Task Map '" << task_name <<
"' does not exist.");
301 double EndPoseProblem::GetRhoEQ(
const std::string& task_name)
303 for (
int i = 0; i < equality.indexing.size(); ++i)
305 if (equality.tasks[i]->GetObjectName() == task_name)
307 return equality.rho(equality.indexing[i].id);
310 ThrowPretty(
"Cannot get rho. Task Map '" << task_name <<
"' does not exist.");
315 for (
int i = 0; i < inequality.indexing.size(); ++i)
317 if (inequality.tasks[i]->GetObjectName() == task_name)
319 if (goal.rows() != inequality.indexing[i].length)
ThrowPretty(
"Expected length of " << inequality.indexing[i].length <<
" and got " << goal.rows());
320 inequality.y.data.segment(inequality.indexing[i].start, inequality.indexing[i].length) = goal;
324 ThrowPretty(
"Cannot set Goal. Task Map '" << task_name <<
"' does not exist.");
327 void EndPoseProblem::SetRhoNEQ(
const std::string& task_name,
const double& rho)
329 for (
int i = 0; i < inequality.indexing.size(); ++i)
331 if (inequality.tasks[i]->GetObjectName() == task_name)
333 inequality.rho(inequality.indexing[i].id) = rho;
338 ThrowPretty(
"Cannot set rho. Task Map '" << task_name <<
"' does not exist.");
341 Eigen::VectorXd EndPoseProblem::GetGoalNEQ(
const std::string& task_name)
343 for (
int i = 0; i < inequality.indexing.size(); ++i)
345 if (inequality.tasks[i]->GetObjectName() == task_name)
347 return inequality.y.data.segment(inequality.indexing[i].start, inequality.indexing[i].length);
350 ThrowPretty(
"Cannot get Goal. Task Map '" << task_name <<
"' does not exist.");
353 double EndPoseProblem::GetRhoNEQ(
const std::string& task_name)
355 for (
int i = 0; i < inequality.indexing.size(); ++i)
357 if (inequality.tasks[i]->GetObjectName() == task_name)
359 return inequality.rho(inequality.indexing[i].id);
362 ThrowPretty(
"Cannot get rho. Task Map '" << task_name <<
"' does not exist.");
365 bool EndPoseProblem::IsValid()
367 std::cout.precision(4);
368 bool succeeded =
true;
370 Eigen::VectorXd
x = scene_->GetKinematicTree().GetControlledState();
371 auto bounds = scene_->GetKinematicTree().GetJointLimits();
374 constexpr
double tolerance = 1.e-3;
375 for (
unsigned int i = 0; i < N; ++i)
377 if (x(i) < bounds(i, 0) - tolerance || x(i) > bounds(i, 1) + tolerance)
379 if (debug_)
HIGHLIGHT_NAMED(
"EndPoseProblem::IsValid",
"Out of bounds (joint #" << i <<
"): " << bounds(i, 0) <<
" < " << x(i) <<
" < " << bounds(i, 1));
385 if (GetInequality().rows() > 0)
387 if (GetInequality().maxCoeff() > parameters_.InequalityFeasibilityTolerance)
389 if (debug_)
HIGHLIGHT_NAMED(
"EndPoseProblem::IsValid",
"Violated inequality constraints: " << GetInequality().transpose());
395 if (GetEquality().rows() > 0)
397 if (GetEquality().cwiseAbs().maxCoeff() > parameters_.EqualityFeasibilityTolerance)
399 if (debug_)
HIGHLIGHT_NAMED(
"EndPoseProblem::IsValid",
"Violated equality constraints: " << GetEquality().cwiseAbs().maxCoeff());
Arbitrarily constrained end-pose problem implementation.
const Eigen::Ref< const Eigen::VectorXd > & VectorXdRefConst
Convenience wrapper for storing references to sub-matrices/vectors.
#define HIGHLIGHT_NAMED(name, x)
Eigen::Ref< Eigen::MatrixXd > MatrixXdRef
void AppendVector(std::vector< Val > &orig, const std::vector< Val > &extra)
#define REGISTER_PROBLEM_TYPE(TYPE, DERIV)