unconstrained_end_pose_problem.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2018-2020, University of Edinburgh, University of Oxford
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of nor the names of its contributors may be used to
14 // endorse or promote products derived from this software without specific
15 // prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
28 //
29 
31 #include <exotica_core/setup.h>
32 
33 REGISTER_PROBLEM_TYPE("UnconstrainedEndPoseProblem", exotica::UnconstrainedEndPoseProblem)
34 
36 {
37 UnconstrainedEndPoseProblem::UnconstrainedEndPoseProblem()
38 {
39  flags_ = KIN_FK | KIN_J;
40 }
41 
42 UnconstrainedEndPoseProblem::~UnconstrainedEndPoseProblem() = default;
43 
44 void UnconstrainedEndPoseProblem::Instantiate(const UnconstrainedEndPoseProblemInitializer& init)
45 {
46  num_tasks = tasks_.size();
47  length_Phi = 0;
48  length_jacobian = 0;
49  for (int i = 0; i < num_tasks; ++i)
50  {
51  AppendVector(Phi.map, tasks_[i]->GetLieGroupIndices());
52  length_Phi += tasks_[i]->length;
53  length_jacobian += tasks_[i]->length_jacobian;
54  }
55  Phi.SetZero(length_Phi);
56  W = Eigen::MatrixXd::Identity(N, N);
57  if (init.W.rows() > 0)
58  {
59  if (init.W.rows() == N)
60  {
61  W.diagonal() = init.W;
62  }
63  else
64  {
65  ThrowNamed("W dimension mismatch! Expected " << N << ", got " << init.W.rows());
66  }
67  }
68  if (flags_ & KIN_J) jacobian = Eigen::MatrixXd(length_jacobian, N);
69  if (flags_ & KIN_H) hessian.setConstant(length_jacobian, Eigen::MatrixXd::Zero(N, N));
70 
71  if (init.NominalState.rows() > 0 && init.NominalState.rows() != N) ThrowNamed("Invalid size of NominalState (" << init.NominalState.rows() << "), expected: " << N);
72  if (init.NominalState.rows() == N) q_nominal = init.NominalState;
73  TaskSpaceVector dummy;
74  cost.Initialize(init.Cost, shared_from_this(), dummy);
75  ApplyStartState(false);
76  PreUpdate();
77 }
78 
79 void UnconstrainedEndPoseProblem::PreUpdate()
80 {
81  PlanningProblem::PreUpdate();
82  for (int i = 0; i < tasks_.size(); ++i) tasks_[i]->is_used = false;
83  cost.UpdateS();
84 }
85 
86 double UnconstrainedEndPoseProblem::GetScalarCost() const
87 {
88  return cost.ydiff.transpose() * cost.S * cost.ydiff;
89 }
90 
91 Eigen::RowVectorXd UnconstrainedEndPoseProblem::GetScalarJacobian() const
92 {
93  return cost.jacobian.transpose() * cost.S * cost.ydiff * 2.0;
94 }
95 
96 double UnconstrainedEndPoseProblem::GetScalarTaskCost(const std::string& task_name) const
97 {
98  const Eigen::VectorXd ydiff = cost.GetTaskError(task_name);
99  return ydiff.transpose() * GetRho(task_name) * ydiff;
100 }
101 
102 void UnconstrainedEndPoseProblem::Update(Eigen::VectorXdRefConst x)
103 {
104  scene_->Update(x, t_start);
105  Phi.SetZero(length_Phi);
106  if (flags_ & KIN_J) jacobian.setZero();
107  if (flags_ & KIN_H)
108  for (int i = 0; i < length_jacobian; ++i) hessian(i).setZero();
109  for (int i = 0; i < tasks_.size(); ++i)
110  {
111  if (tasks_[i]->is_used)
112  {
113  if (flags_ & KIN_H)
114  {
115  tasks_[i]->Update(x,
116  Phi.data.segment(tasks_[i]->start, tasks_[i]->length),
117  jacobian.middleRows(tasks_[i]->start_jacobian, tasks_[i]->length_jacobian),
118  hessian.segment(tasks_[i]->start_jacobian, tasks_[i]->length_jacobian));
119  }
120  else if (flags_ & KIN_J)
121  {
122  tasks_[i]->Update(x,
123  Phi.data.segment(tasks_[i]->start, tasks_[i]->length),
124  Eigen::MatrixXdRef(jacobian.middleRows(tasks_[i]->start_jacobian, tasks_[i]->length_jacobian)) // Adding MatrixXdRef(...) is a work-around for issue #737 when using Eigen 3.3.9
125  );
126  }
127  else
128  {
129  tasks_[i]->Update(x, Phi.data.segment(tasks_[i]->start, tasks_[i]->length));
130  }
131  }
132  }
133  if (flags_ & KIN_H)
134  {
135  cost.Update(Phi, jacobian, hessian);
136  }
137  else if (flags_ & KIN_J)
138  {
139  cost.Update(Phi, jacobian);
140  }
141  else
142  {
143  cost.Update(Phi);
144  }
145  ++number_of_problem_updates_;
146 }
147 
148 void UnconstrainedEndPoseProblem::SetGoal(const std::string& task_name, Eigen::VectorXdRefConst goal)
149 {
150  for (int i = 0; i < cost.indexing.size(); ++i)
151  {
152  if (cost.tasks[i]->GetObjectName() == task_name)
153  {
154  if (goal.rows() != cost.indexing[i].length) ThrowPretty("Expected length of " << cost.indexing[i].length << " and got " << goal.rows());
155  cost.y.data.segment(cost.indexing[i].start, cost.indexing[i].length) = goal;
156  return;
157  }
158  }
159  ThrowPretty("Cannot set Goal. Task map '" << task_name << "' does not exist.");
160 }
161 
162 void UnconstrainedEndPoseProblem::SetRho(const std::string& task_name, const double& rho)
163 {
164  for (int i = 0; i < cost.indexing.size(); ++i)
165  {
166  if (cost.tasks[i]->GetObjectName() == task_name)
167  {
168  cost.rho(cost.indexing[i].id) = rho;
169  PreUpdate();
170  return;
171  }
172  }
173  ThrowPretty("Cannot set rho. Task map '" << task_name << "' does not exist.");
174 }
175 
176 Eigen::VectorXd UnconstrainedEndPoseProblem::GetGoal(const std::string& task_name) const
177 {
178  for (int i = 0; i < cost.indexing.size(); ++i)
179  {
180  if (cost.tasks[i]->GetObjectName() == task_name)
181  {
182  return cost.y.data.segment(cost.indexing[i].start, cost.indexing[i].length);
183  }
184  }
185  ThrowPretty("Cannot get Goal. Task map '" << task_name << "' does not exist.");
186 }
187 
188 double UnconstrainedEndPoseProblem::GetRho(const std::string& task_name) const
189 {
190  for (int i = 0; i < cost.indexing.size(); ++i)
191  {
192  if (cost.tasks[i]->GetObjectName() == task_name)
193  {
194  return cost.rho(cost.indexing[i].id);
195  }
196  }
197  ThrowPretty("Cannot get rho. Task map '" << task_name << "' does not exist.");
198 }
199 
200 Eigen::VectorXd UnconstrainedEndPoseProblem::GetNominalPose() const
201 {
202  return q_nominal;
203 }
204 
205 void UnconstrainedEndPoseProblem::SetNominalPose(Eigen::VectorXdRefConst qNominal_in)
206 {
207  if (qNominal_in.rows() == N)
208  q_nominal = qNominal_in;
209  else
210  ThrowPretty("Cannot set q_nominal - wrong number of rows (expected "
211  << N << ", received " << qNominal_in.rows() << ").");
212 }
213 
214 int UnconstrainedEndPoseProblem::GetTaskId(const std::string& task_name) const
215 {
216  for (int i = 0; i < cost.indexing.size(); ++i)
217  {
218  if (cost.tasks[i]->GetObjectName() == task_name)
219  {
220  return i;
221  }
222  }
223  ThrowPretty("Cannot get task. Task map '" << task_name << "' does not exist.");
224 }
225 } // namespace exotica
#define ThrowPretty(m)
Definition: exception.h:36
#define ThrowNamed(m)
Definition: exception.h:42
const Eigen::Ref< const Eigen::VectorXd > & VectorXdRefConst
Convenience wrapper for storing references to sub-matrices/vectors.
Definition: conversions.h:52
Eigen::Ref< Eigen::MatrixXd > MatrixXdRef
Definition: conversions.h:55
void AppendVector(std::vector< Val > &orig, const std::vector< Val > &extra)
Definition: conversions.h:223
#define REGISTER_PROBLEM_TYPE(TYPE, DERIV)


exotica_core
Author(s): Yiming Yang, Michael Camilleri
autogenerated on Sat Apr 10 2021 02:34:49