sampling_problem.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2018, University of Edinburgh
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 
34 
36 {
37 SamplingProblem::SamplingProblem()
38 {
39  flags_ = KIN_FK;
40 }
41 
42 SamplingProblem::~SamplingProblem() = default;
43 
44 std::vector<double> SamplingProblem::GetBounds()
45 {
46  std::vector<double> bounds;
47  auto joint_limits = scene_->GetKinematicTree().GetJointLimits();
48 
49  bounds.resize(2 * N);
50  for (unsigned int i = 0; i < N; ++i)
51  {
52  bounds[i] = joint_limits(i, 0);
53  bounds[i + N] = joint_limits(i, 1);
54  }
55 
56  return bounds;
57 }
58 
59 void SamplingProblem::Instantiate(const SamplingProblemInitializer& init)
60 {
61  if (init.Goal.size() == N)
62  {
63  goal_ = init.Goal;
64  }
65  else if (init.Goal.size() == 0)
66  {
67  goal_ = Eigen::VectorXd::Zero(N);
68  }
69  else
70  {
71  ThrowNamed("Dimension mismatch: problem N=" << N << ", but goal state has dimension " << init.Goal.size());
72  }
73 
74  compound_ = scene_->GetKinematicTree().GetControlledBaseType() != exotica::BaseType::FIXED;
75 
76  num_tasks = tasks_.size();
77  length_Phi = 0;
78  length_jacobian = 0;
79  for (int i = 0; i < num_tasks; ++i)
80  {
81  AppendVector(Phi.map, tasks_[i]->GetLieGroupIndices());
82  length_Phi += tasks_[i]->length;
83  length_jacobian += tasks_[i]->length_jacobian;
84  }
85  Phi.SetZero(length_Phi);
86  TaskSpaceVector dummy;
87  inequality.Initialize(init.Inequality, shared_from_this(), dummy);
88  inequality.tolerance = init.ConstraintTolerance;
89  equality.Initialize(init.Equality, shared_from_this(), dummy);
90  equality.tolerance = init.ConstraintTolerance;
91  ApplyStartState(false);
92 
93  if (compound_ && init.FloatingBaseLowerLimits.rows() > 0 && init.FloatingBaseUpperLimits.rows() > 0)
94  {
95  if (scene_->GetKinematicTree().GetControlledBaseType() == exotica::BaseType::FLOATING && init.FloatingBaseLowerLimits.rows() == 6 && init.FloatingBaseUpperLimits.rows() == 6)
96  {
97  scene_->GetKinematicTree().SetFloatingBaseLimitsPosXYZEulerZYX(
98  std::vector<double>(init.FloatingBaseLowerLimits.data(), init.FloatingBaseLowerLimits.data() + init.FloatingBaseLowerLimits.size()),
99  std::vector<double>(init.FloatingBaseUpperLimits.data(), init.FloatingBaseUpperLimits.data() + init.FloatingBaseUpperLimits.size()));
100  }
101  else if (scene_->GetKinematicTree().GetControlledBaseType() == exotica::BaseType::PLANAR && init.FloatingBaseLowerLimits.rows() == 3 && init.FloatingBaseUpperLimits.rows() == 3)
102  {
103  scene_->GetKinematicTree().SetPlanarBaseLimitsPosXYEulerZ(
104  std::vector<double>(init.FloatingBaseLowerLimits.data(), init.FloatingBaseLowerLimits.data() + init.FloatingBaseLowerLimits.size()),
105  std::vector<double>(init.FloatingBaseUpperLimits.data(), init.FloatingBaseUpperLimits.data() + init.FloatingBaseUpperLimits.size()));
106  }
107  else
108  {
109  ThrowNamed("Invalid base limits!");
110  }
111  }
112 
113  PreUpdate();
114 }
115 
116 void SamplingProblem::PreUpdate()
117 {
118  PlanningProblem::PreUpdate();
119  for (int i = 0; i < tasks_.size(); ++i) tasks_[i]->is_used = false;
120  inequality.UpdateS();
121  equality.UpdateS();
122 }
123 
124 void SamplingProblem::SetGoalState(Eigen::VectorXdRefConst qT)
125 {
126  if (qT.rows() != N)
127  ThrowPretty("Dimensionality of goal state wrong: Got " << qT.rows() << ", expected " << N);
128  goal_ = qT;
129 }
130 
131 void SamplingProblem::SetGoalEQ(const std::string& task_name, Eigen::VectorXdRefConst goal)
132 {
133  for (int i = 0; i < equality.indexing.size(); ++i)
134  {
135  if (equality.tasks[i]->GetObjectName() == task_name)
136  {
137  if (goal.rows() != equality.indexing[i].length) ThrowPretty("Expected length of " << equality.indexing[i].length << " and got " << goal.rows());
138  equality.y.data.segment(equality.indexing[i].start, equality.indexing[i].length) = goal;
139  return;
140  }
141  }
142  ThrowPretty("Cannot set Goal. Task map '" << task_name << "' does not exist.");
143 }
144 
145 void SamplingProblem::SetRhoEQ(const std::string& task_name, const double& rho)
146 {
147  for (int i = 0; i < equality.indexing.size(); ++i)
148  {
149  if (equality.tasks[i]->GetObjectName() == task_name)
150  {
151  equality.rho(equality.indexing[i].id) = rho;
152  PreUpdate();
153  return;
154  }
155  }
156  ThrowPretty("Cannot set rho. Task map '" << task_name << "' does not exist.");
157 }
158 
159 Eigen::VectorXd SamplingProblem::GetGoalEQ(const std::string& task_name)
160 {
161  for (int i = 0; i < equality.indexing.size(); ++i)
162  {
163  if (equality.tasks[i]->GetObjectName() == task_name)
164  {
165  return equality.y.data.segment(equality.indexing[i].start, equality.indexing[i].length);
166  }
167  }
168  ThrowPretty("Cannot get Goal. Task map '" << task_name << "' does not exist.");
169 }
170 
171 double SamplingProblem::GetRhoEQ(const std::string& task_name)
172 {
173  for (int i = 0; i < equality.indexing.size(); ++i)
174  {
175  if (equality.tasks[i]->GetObjectName() == task_name)
176  {
177  return equality.rho(equality.indexing[i].id);
178  }
179  }
180  ThrowPretty("Cannot get rho. Task map '" << task_name << "' does not exist.");
181 }
182 
183 void SamplingProblem::SetGoalNEQ(const std::string& task_name, Eigen::VectorXdRefConst goal)
184 {
185  for (int i = 0; i < inequality.indexing.size(); ++i)
186  {
187  if (inequality.tasks[i]->GetObjectName() == task_name)
188  {
189  if (goal.rows() != inequality.indexing[i].length) ThrowPretty("Expected length of " << inequality.indexing[i].length << " and got " << goal.rows());
190  inequality.y.data.segment(inequality.indexing[i].start, inequality.indexing[i].length) = goal;
191  return;
192  }
193  }
194  ThrowPretty("Cannot set Goal. Task map '" << task_name << "' does not exist.");
195 }
196 
197 void SamplingProblem::SetRhoNEQ(const std::string& task_name, const double& rho)
198 {
199  for (int i = 0; i < inequality.indexing.size(); ++i)
200  {
201  if (inequality.tasks[i]->GetObjectName() == task_name)
202  {
203  inequality.rho(inequality.indexing[i].id) = rho;
204  PreUpdate();
205  return;
206  }
207  }
208  ThrowPretty("Cannot set rho. Task map '" << task_name << "' does not exist.");
209 }
210 
211 Eigen::VectorXd SamplingProblem::GetGoalNEQ(const std::string& task_name)
212 {
213  for (int i = 0; i < inequality.indexing.size(); ++i)
214  {
215  if (inequality.tasks[i]->GetObjectName() == task_name)
216  {
217  return inequality.y.data.segment(inequality.indexing[i].start, inequality.indexing[i].length);
218  }
219  }
220  ThrowPretty("Cannot get Goal. Task map '" << task_name << "' does not exist.");
221 }
222 
223 double SamplingProblem::GetRhoNEQ(const std::string& task_name)
224 {
225  for (int i = 0; i < inequality.indexing.size(); ++i)
226  {
227  if (inequality.tasks[i]->GetObjectName() == task_name)
228  {
229  return inequality.rho(inequality.indexing[i].id);
230  }
231  }
232  ThrowPretty("Cannot get rho. Task map '" << task_name << "' does not exist.");
233 }
234 
235 void SamplingProblem::Update(Eigen::VectorXdRefConst x)
236 {
237  scene_->Update(x);
238  for (int i = 0; i < num_tasks; ++i)
239  {
240  if (tasks_[i]->is_used)
241  tasks_[i]->Update(x, Phi.data.segment(tasks_[i]->start, tasks_[i]->length));
242  }
243  inequality.Update(Phi);
244  equality.Update(Phi);
245  ++number_of_problem_updates_;
246 }
247 
248 bool SamplingProblem::IsValid()
249 {
250  // Check bounds
251  const Eigen::VectorXd x = scene_->GetKinematicTree().GetControlledState();
252  const Eigen::MatrixXd bounds = scene_->GetKinematicTree().GetJointLimits();
253  for (int i = 0; i < N; ++i)
254  {
255  if (x(i) < bounds(i, 0) || x(i) > bounds(i, 1))
256  {
257  if (debug_) HIGHLIGHT_NAMED("SamplingProblem::IsValid", "State is out of bounds: joint #" << i << ": " << bounds(i, 0) << " < " << x(i) << " < " << bounds(i, 1));
258  return false;
259  }
260  }
261 
262  // Check constraints
263  const bool inequality_is_valid = ((inequality.S * inequality.ydiff).array() <= 0.0).all();
264  const bool equality_is_valid = ((equality.S * equality.ydiff).array().abs() == 0.0).all();
265 
266  if (debug_)
267  {
268  HIGHLIGHT_NAMED("SamplingProblem::IsValid", "NEQ = " << std::boolalpha << inequality_is_valid << ", EQ = " << equality_is_valid);
269  if (!equality_is_valid)
270  {
271  HIGHLIGHT_NAMED("SamplingProblem::IsValid", "Equality: ydiff = " << equality.ydiff.transpose() << ", S * ydiff = " << (equality.S * equality.ydiff).transpose());
272  }
273  if (!inequality_is_valid)
274  {
275  HIGHLIGHT_NAMED("SamplingProblem::IsValid", "Inequality: ydiff = " << inequality.ydiff.transpose() << ", S * ydiff = " << (inequality.S * inequality.ydiff).transpose());
276  }
277  }
278 
279  return (inequality_is_valid && equality_is_valid);
280 }
281 
282 bool SamplingProblem::IsStateValid(Eigen::VectorXdRefConst x)
283 {
284  Update(x);
285  return IsValid();
286 }
287 
288 int SamplingProblem::GetSpaceDim()
289 {
290  return N;
291 }
292 
293 bool SamplingProblem::IsCompoundStateSpace()
294 {
295  return compound_;
296 }
297 } // 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
#define HIGHLIGHT_NAMED(name, x)
Definition: printable.h:62
void AppendVector(std::vector< Val > &orig, const std::vector< Val > &extra)
Definition: conversions.h:223
double x
#define REGISTER_PROBLEM_TYPE(TYPE, DERIV)


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