ocra-recipes
Doxygen documentation for the ocra-recipes repository
FSQPConstraintManager.cpp
Go to the documentation of this file.
2 #include <algorithm>
3 
4 namespace
5 {
6  int getConstraintOnesidedDimension(const ocra::GenericConstraint* c)
7  {
9  return 2*c->getDimension();
10  else return c->getDimension();
11  }
12 }
13 
14 
15 namespace ocra
16 {
18  {
19  return m1.length < m2.length;
20  }
21 
23  : _invalidatedIndex(0)
24  , _nineqn(0)
25  , _nineq(0)
26  , _neqn(0)
27  , _neq(0)
28  {
29  _mappings.push_back(Mapping());
30  }
31 
33  {
34  const int ni = (int)(_nonLinearIneq.size()+_linearIneq.size());
35  if (constraint.isEquality())
36  {
37  _invalidatedIndex = std::min(_invalidatedIndex, ni+(int)(_nonLinearEq.size()+_linearEq.size()));
38  _linearEq.push_back(&constraint);
39  }
40  else
41  {
42  _invalidatedIndex = std::min(_invalidatedIndex, ni);
43  _linearIneq.push_back(&constraint);
44  }
45  }
46 
48  {
49  if (constraint.isEquality())
50  {
51  _invalidatedIndex = std::min(_invalidatedIndex, (int)(_nonLinearIneq.size()+_linearIneq.size()+_nonLinearIneq.size()));
52  _nonLinearEq.push_back(&constraint);
53  }
54  else
55  {
56  _invalidatedIndex = std::min(_invalidatedIndex, (int)_nonLinearIneq.size());
57  _nonLinearIneq.push_back(&constraint);
58  }
59  }
60 
62  {
63  if (constraint.isEquality())
64  {
65  std::vector<LinearConstraint*>::iterator it = std::find(_linearEq.begin(), _linearEq.end(), &constraint);
66  if (it != _linearEq.end())
67  {
68  _invalidatedIndex = std::min(_invalidatedIndex, (int)(_nonLinearIneq.size()+_linearIneq.size()+_nonLinearEq.size())+(int)(it-_linearEq.begin()));
69  _linearEq.erase(it);
70  }
71  }
72  else
73  {
74  std::vector<LinearConstraint*>::iterator it = std::find(_linearIneq.begin(), _linearIneq.end(), &constraint);
75  if (it != _linearIneq.end())
76  {
77  _invalidatedIndex = std::min(_invalidatedIndex, (int)_nonLinearIneq.size()+(int)(it-_linearIneq.begin()));
78  _linearIneq.erase(it);
79  }
80  }
81  }
82 
84  {
85  if (constraint.isEquality())
86  {
87  std::vector<GenericConstraint*>::iterator it = std::find(_nonLinearEq.begin(), _nonLinearEq.end(), &constraint);
88  if (it != _nonLinearEq.end())
89  {
90  _invalidatedIndex = std::min(_invalidatedIndex, (int)(_nonLinearIneq.size()+_linearIneq.size())+(int)(it-_nonLinearEq.begin()));
91  _nonLinearEq.erase(it);
92  }
93  }
94  else
95  {
96  std::vector<GenericConstraint*>::iterator it = std::find(_nonLinearIneq.begin(), _nonLinearIneq.end(), &constraint);
97  if (it != _nonLinearIneq.end())
98  {
99  _invalidatedIndex = std::min(_invalidatedIndex, (int)(it-_nonLinearIneq.begin()));
100  _nonLinearIneq.erase(it);
101  }
102  }
103  }
104 
106  {
107  if (_invalidatedIndex == std::numeric_limits<int>::max())
108  return ;
109 
110  const size_t n1 = _nonLinearIneq.size();
111  const size_t n2 = _linearIneq.size() + n1;
112  const size_t n3 = _nonLinearEq.size() + n2;
113  const size_t n4 = _linearEq.size() + n3;
114  const size_t n = n4+1;
115 
116  // 1. Resize the vector if needed
117  if (n<_mappings.size())
118  _mappings.resize(n);
119  else
120  {
121  for (size_t i=_mappings.size(); i<n; ++i)
122  _mappings.push_back(Mapping(static_cast<int>(i)));
123  }
124 
125  // 2. Update the counting values
126  size_t i = _invalidatedIndex;
127  for (;i<n1; ++i)
128  _mappings[i+1].length = _mappings[i].length + getConstraintOnesidedDimension(_nonLinearIneq[i]);
129  _nineqn = _mappings[i].length;
130  for (;i<n2; ++i)
131  _mappings[i+1].length = _mappings[i].length + getConstraintOnesidedDimension(_linearIneq[i-n1]);
132  _nineq = _mappings[i].length;
133  for (;i<n3; ++i)
134  _mappings[i+1].length = _mappings[i].length + getConstraintOnesidedDimension(_nonLinearEq[i-n2]);
135  _neqn = _mappings[i].length - _nineq;
136  for (;i<n4; ++i)
137  _mappings[i+1].length = _mappings[i].length + getConstraintOnesidedDimension(_linearEq[i-n3]);
138  _neq = _mappings[i].length - _nineq;
139 
140  _invalidatedIndex = std::numeric_limits<int>::max();
141  }
142 
144  {
145  _invalidatedIndex = 0;
146  }
147 
148  std::pair<GenericConstraint*, int> FSQPConstraintManager::operator[] (int i) const
149  {
150  if (_invalidatedIndex != std::numeric_limits<int>::max())
151  updateMapping();
152 
153  std::vector<Mapping>::iterator it = std::upper_bound(_mappings.begin(), _mappings.end(), Mapping(i,0));
154  assert(it != _mappings.end());
155  --it;
156  size_t j = it->index;
157  if (j<_nonLinearIneq.size())
158  return std::make_pair(_nonLinearIneq[j], i-it->length);
159 
160  j -= _nonLinearIneq.size();
161  if (j<_linearIneq.size())
162  return std::make_pair(_linearIneq[j], i-it->length);
163 
164  j -= _linearIneq.size();
165  if (j<_nonLinearEq.size())
166  return std::make_pair(_nonLinearEq[j], i-it->length);
167 
168  j -= _nonLinearEq.size();
169  return std::make_pair(_linearEq[j], i-it->length);
170  }
171 
173  {
174  std::pair<const GenericConstraint*, int> p = (*this)[i];
175 
176  switch (p.first->getType())
177  {
178  case CSTR_EQUAL_ZERO: return p.first->getValue(p.second);
179  case CSTR_EQUAL_B: return p.first->getValue(p.second) - p.first->getB()[p.second];
180  case CSTR_LOWER_ZERO: return p.first->getValue(p.second);
181  case CSTR_LOWER_U: return p.first->getValue(p.second) - p.first->getU()[p.second];
182  case CSTR_GREATER_ZERO: return -p.first->getValue(p.second);
183  case CSTR_GREATER_L: return -p.first->getValue(p.second) + p.first->getL()[p.second];
185  if (p.second<p.first->getDimension())
186  return -p.first->getValue(p.second) + p.first->getL()[p.second];
187  else
188  {
189  const int n = p.second - p.first->getDimension();
190  return p.first->getValue(n) - p.first->getU()[n];
191  }
192  default:
193  ocra_assert(false && "this should never happen");
194  }
195 
196  return -1; // should never happen, just to avoid warnings
197  }
198 
200  {
201  std::pair<GenericConstraint*, int> p = (*this)[i];
202  return getGradient(p);
203  }
204 
205  const FSQPConstraintManager::ScalarMultMatrixXdRow FSQPConstraintManager::getGradient(const std::pair<GenericConstraint*, int>& p) const
206  {
207  ocra_assert(p.first->canCompute<PARTIAL_X>());
208  ocra_assert(p.second < p.first->getDimension() || (p.first->getType() == CSTR_LOWER_AND_GREATER && p.second < 2*p.first->getDimension()));
209 
210  switch (p.first->getType())
211  {
212  case CSTR_EQUAL_ZERO: return 1.*p.first->getJacobian(p.second);
213  case CSTR_EQUAL_B: return 1.*p.first->getJacobian(p.second);
214  case CSTR_LOWER_ZERO: return 1.*p.first->getJacobian(p.second);
215  case CSTR_LOWER_U: return 1.*p.first->getJacobian(p.second);
216  case CSTR_GREATER_ZERO: return -1.*p.first->getJacobian(p.second);
217  case CSTR_GREATER_L: return -1.*p.first->getJacobian(p.second);
219  if (p.second<p.first->getDimension())
220  return -1.*p.first->getJacobian(p.second);
221  else
222  return 1.*p.first->getJacobian(p.second - p.first->getDimension());
223  default:
224  ocra_assert(false && "this should never happen");
225  }
226  }
227 }
228 
232 
233 namespace ocra
234 {
236  {
237  const int n=5;
238  BaseVariable x("x", n);
239  EqualZeroConstraintPtr<LinearFunction> el1(new LinearFunction(x, MatrixXd::Random(3,n), VectorXd::Random(3)));
240  EqualZeroConstraintPtr<LinearFunction> el2(new LinearFunction(x, MatrixXd::Random(4,n), VectorXd::Random(4)));
241  EqualZeroConstraintPtr<LinearFunction> el3(new LinearFunction(x, MatrixXd::Random(2,n), VectorXd::Random(2)));
242 
243  LessThanZeroConstraintPtr<LinearFunction> il1(new LinearFunction(x, MatrixXd::Random(2,n), VectorXd::Random(2)));
244  LessThanZeroConstraintPtr<LinearFunction> il2(new LinearFunction(x, MatrixXd::Random(1,n), VectorXd::Random(1)));
245  LessThanZeroConstraintPtr<LinearFunction> il3(new LinearFunction(x, MatrixXd::Random(2,n), VectorXd::Random(2)));
246 
247  MatrixXd P = MatrixXd::Random(n,n);
248  P = P.transpose()*P;
249 
250  EqualZeroConstraintPtr<QuadraticFunction> eq1(new QuadraticFunction(x, P, VectorXd::Random(n), 0.));
251  EqualZeroConstraintPtr<QuadraticFunction> eq2(new QuadraticFunction(x, P, VectorXd::Random(n), 0.));
252 
253  LessThanZeroConstraintPtr<QuadraticFunction> iq1(new QuadraticFunction(x, P, VectorXd::Random(n), 0.));
254  LessThanZeroConstraintPtr<QuadraticFunction> iq2(new QuadraticFunction(x, P, VectorXd::Random(n), 0.));
255 
256 
258  m.addConstraint(el1);
259  m.updateMapping();
260  m.addConstraint(iq1);
261  m.updateMapping();
262  m.addConstraint(eq1);
263  m.updateMapping();
264  m.addConstraint(il1);
265  m.updateMapping();
266 
267  m[2];
268  m[5];
269 
270  m.removeConstraint(il1);
271  m.updateMapping();
272  }
273 }
bool operator<(const FSQPConstraintManager::Mapping &m1, const FSQPConstraintManager::Mapping &m2)
void addConstraint(LinearConstraint &constraint)
FSQPConstraintManager class.
LinearFunction class.
void testFsqpMapping()
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
Constraint class.
Definition: Constraint.h:100
std::pair< GenericConstraint *, int > operator[](int i) const
Declaration file of the LinearFunction class.
void removeConstraint(LinearConstraint &constraint)
const ScalarMultMatrixXdRow getGradient(int i) const
Declaration file of the FSQPConstraintManager class.
eConstraintType getType() const
Definition: Constraint.h:538
#define ocra_assert(ocra_expression)
Definition: ocra_assert.h:45
QuadraticFunction class.
CwiseUnaryOp< internal::scalar_multiple_op< double >, MatrixXdRow > ScalarMultMatrixXdRow
Implements a basic variable.
Definition: Variable.h:304
Declaration file of the QuadraticFunction class.