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 
35 namespace exotica
36 {
38 {
39  flags_ = KIN_FK;
40 }
41 
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  }
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 
117 {
119  for (int i = 0; i < tasks_.size(); ++i) tasks_[i]->is_used = false;
121  equality.UpdateS();
122 }
123 
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 
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  }
246 }
247 
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 
283 {
284  Update(x);
285  return IsValid();
286 }
287 
289 {
290  return N;
291 }
292 
294 {
295  return compound_;
296 }
297 } // namespace exotica
exotica::PlanningProblem::number_of_problem_updates_
unsigned int number_of_problem_updates_
Definition: planning_problem.h:111
exotica::AppendVector
void AppendVector(std::vector< Val > &orig, const std::vector< Val > &extra)
Definition: conversions.h:223
exotica::SamplingProblem::SetGoalEQ
void SetGoalEQ(const std::string &task_name, Eigen::VectorXdRefConst goal)
Definition: sampling_problem.cpp:131
exotica::SamplingProblem::SetGoalNEQ
void SetGoalNEQ(const std::string &task_name, Eigen::VectorXdRefConst goal)
Definition: sampling_problem.cpp:183
exotica::SamplingProblem::Phi
TaskSpaceVector Phi
Definition: sampling_problem.h:70
exotica::PlanningProblem::flags_
KinematicRequestFlags flags_
Definition: planning_problem.h:109
exotica::PLANAR
@ PLANAR
Definition: kinematic_tree.h:53
exotica::SamplingProblem::GetRhoNEQ
double GetRhoNEQ(const std::string &task_name)
Definition: sampling_problem.cpp:223
exotica::SamplingTask::Initialize
virtual void Initialize(const std::vector< exotica::Initializer > &inits, std::shared_ptr< PlanningProblem > prob, TaskSpaceVector &Phi)
Definition: tasks.cpp:494
exotica::SamplingProblem::SamplingProblem
SamplingProblem()
Definition: sampling_problem.cpp:37
exotica::SamplingProblem::GetGoalEQ
Eigen::VectorXd GetGoalEQ(const std::string &task_name)
Definition: sampling_problem.cpp:159
exotica::SamplingProblem::length_jacobian
int length_jacobian
Definition: sampling_problem.h:75
exotica::SamplingProblem::SetRhoEQ
void SetRhoEQ(const std::string &task_name, const double &rho)
Definition: sampling_problem.cpp:145
exotica::SamplingProblem
Definition: sampling_problem.h:40
exotica::SamplingProblem::num_tasks
int num_tasks
Definition: sampling_problem.h:76
exotica::SamplingProblem::SetRhoNEQ
void SetRhoNEQ(const std::string &task_name, const double &rho)
Definition: sampling_problem.cpp:197
exotica::PlanningProblem::N
int N
Definition: planning_problem.h:97
exotica
Definition: collision_scene.h:46
exotica::FLOATING
@ FLOATING
Definition: kinematic_tree.h:52
exotica::SamplingProblem::Instantiate
void Instantiate(const SamplingProblemInitializer &init) override
Definition: sampling_problem.cpp:59
exotica::PlanningProblem::tasks_
TaskMapVec tasks_
Definition: planning_problem.h:108
exotica::SamplingTask::rho
Eigen::VectorXd rho
Definition: tasks.h:172
HIGHLIGHT_NAMED
#define HIGHLIGHT_NAMED(name, x)
Definition: printable.h:62
exotica::SamplingTask::Update
void Update(const TaskSpaceVector &big_Phi)
Definition: tasks.cpp:545
exotica::KIN_FK
@ KIN_FK
Definition: kinematic_tree.h:58
exotica::PlanningProblem::scene_
ScenePtr scene_
Definition: planning_problem.h:106
exotica::SamplingProblem::compound_
bool compound_
Definition: sampling_problem.h:80
exotica::SamplingProblem::IsStateValid
bool IsStateValid(Eigen::VectorXdRefConst x)
Definition: sampling_problem.cpp:282
exotica::SamplingProblem::GetSpaceDim
int GetSpaceDim()
Definition: sampling_problem.cpp:288
Eigen::VectorXdRefConst
const typedef Eigen::Ref< const Eigen::VectorXd > & VectorXdRefConst
Convenience wrapper for storing references to sub-matrices/vectors.
Definition: conversions.h:52
REGISTER_PROBLEM_TYPE
#define REGISTER_PROBLEM_TYPE(TYPE, DERIV)
Definition: planning_problem.h:45
exotica::TaskSpaceVector
Definition: task_space_vector.h:50
exotica::SamplingProblem::GetRhoEQ
double GetRhoEQ(const std::string &task_name)
Definition: sampling_problem.cpp:171
exotica::SamplingTask::y
TaskSpaceVector y
Definition: tasks.h:173
exotica::SamplingTask::ydiff
Eigen::VectorXd ydiff
Definition: tasks.h:174
exotica::Object::debug_
bool debug_
Definition: object.h:86
sampling_problem.h
exotica::TaskSpaceVector::map
std::vector< TaskVectorEntry > map
Definition: task_space_vector.h:59
exotica::SamplingProblem::GetBounds
std::vector< double > GetBounds()
Definition: sampling_problem.cpp:44
exotica::Task::indexing
std::vector< TaskIndexing > indexing
Definition: tasks.h:64
exotica::SamplingProblem::goal_
Eigen::VectorXd goal_
Definition: sampling_problem.h:79
setup.h
exotica::SamplingProblem::IsCompoundStateSpace
bool IsCompoundStateSpace()
Definition: sampling_problem.cpp:293
ThrowPretty
#define ThrowPretty(m)
Definition: exception.h:36
exotica::SamplingProblem::Update
void Update(Eigen::VectorXdRefConst x)
Definition: sampling_problem.cpp:235
exotica::Task::tolerance
double tolerance
Definition: tasks.h:69
exotica::SamplingProblem::SetGoalState
void SetGoalState(Eigen::VectorXdRefConst qT)
Definition: sampling_problem.cpp:124
exotica::PlanningProblem::ApplyStartState
virtual Eigen::VectorXd ApplyStartState(bool update_traj=true)
Definition: planning_problem.cpp:70
exotica::Task::tasks
TaskMapVec tasks
Definition: tasks.h:63
init
void init(const M_string &remappings)
exotica::TaskSpaceVector::data
Eigen::VectorXd data
Definition: task_space_vector.h:58
x
double x
exotica::SamplingProblem::equality
SamplingTask equality
Definition: sampling_problem.h:72
exotica::FIXED
@ FIXED
Definition: kinematic_tree.h:51
exotica::PlanningProblem::PreUpdate
virtual void PreUpdate()
Definition: planning_problem.cpp:86
exotica::SamplingProblem::PreUpdate
void PreUpdate() override
Definition: sampling_problem.cpp:116
exotica::SamplingProblem::GetGoalNEQ
Eigen::VectorXd GetGoalNEQ(const std::string &task_name)
Definition: sampling_problem.cpp:211
exotica::SamplingProblem::IsValid
bool IsValid() override
Evaluates whether the problem is valid.
Definition: sampling_problem.cpp:248
exotica::SamplingTask::UpdateS
void UpdateS()
Definition: tasks.cpp:533
exotica::SamplingProblem::length_Phi
int length_Phi
Definition: sampling_problem.h:74
exotica::TaskSpaceVector::SetZero
void SetZero(const int n)
Definition: task_space_vector.cpp:54
ThrowNamed
#define ThrowNamed(m)
Definition: exception.h:42
exotica::SamplingProblem::~SamplingProblem
virtual ~SamplingProblem()
exotica::SamplingProblem::inequality
SamplingTask inequality
Definition: sampling_problem.h:71
exotica::SamplingTask::S
Eigen::MatrixXd S
Definition: tasks.h:176


exotica_core
Author(s): Yiming Yang, Michael Camilleri
autogenerated on Fri Oct 20 2023 02:59:49