finite_differences_grid_move_blocking.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement
4  *
5  * Copyright (c) 2020,
6  * TU Dortmund - Institute of Control Theory and Systems Engineering.
7  * All rights reserved.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <https://www.gnu.org/licenses/>.
21  *
22  * Authors: Maximilian Krämer, Christoph Rösmann
23  *********************************************************************/
24 
28 
29 namespace corbo {
30 
32 {
33  assert(isValid());
34 
35  // clear edges first
36  // TODO(roesmann): we could implement a more efficient strategy without recreating the whole edgeset everytime
37  edges.clear();
38 
39  int n = getN();
40 
41  std::vector<BaseEdge::Ptr> cost_terms, eq_terms, ineq_terms;
42  int u_idx = 0;
43  int block_idx = -1;
44 
45  for (int k = 0; k < n - 1; ++k)
46  {
47  // update move blocking index
48  if (k == u_idx)
49  {
50  ++block_idx;
51  u_idx += _blocking_vector(block_idx);
52  }
53 
54  VectorVertex& x_next = (k < n - 2) ? _x_seq[k + 1] : _xf;
55 
56  VectorVertex& u_prev = (block_idx > 0) ? _u_seq[block_idx - 1] : _u_prev;
57  ScalarVertex& dt_prev = (k > 0) ? _dt : _u_prev_dt;
58 
59  cost_terms.clear();
60  eq_terms.clear();
61  ineq_terms.clear();
62 
63  nlp_fun.getNonIntegralStageFunctionEdges(k, _x_seq[k], _u_seq[block_idx], _dt, u_prev, dt_prev, cost_terms, eq_terms, ineq_terms);
64  for (BaseEdge::Ptr& edge : cost_terms) edges.addObjectiveEdge(edge);
65  for (BaseEdge::Ptr& edge : eq_terms) edges.addEqualityEdge(edge);
66  for (BaseEdge::Ptr& edge : ineq_terms) edges.addInequalityEdge(edge);
67 
68  if (nlp_fun.stage_cost && nlp_fun.stage_cost->hasIntegralTerms(k))
69  {
71  {
73  std::make_shared<TrapezoidalIntegralCostEdge>(_x_seq[k], _u_seq[block_idx], x_next, _dt, nlp_fun.stage_cost, k);
74  edges.addObjectiveEdge(edge);
75  }
77  {
78  LeftSumCostEdge::Ptr edge = std::make_shared<LeftSumCostEdge>(_x_seq[k], _u_seq[block_idx], _dt, nlp_fun.stage_cost, k);
79  edges.addObjectiveEdge(edge);
80  }
81  else
82  PRINT_ERROR_NAMED("Cost integration rule not implemented");
83  }
84 
85  if (nlp_fun.stage_equalities && nlp_fun.stage_equalities->hasIntegralTerms(k))
86  {
88  {
89  TrapezoidalIntegralEqualityDynamicsEdge::Ptr edge = std::make_shared<TrapezoidalIntegralEqualityDynamicsEdge>(
90  dynamics, _x_seq[k], _u_seq[block_idx], x_next, _dt, nlp_fun.stage_equalities, k);
91  edge->setFiniteDifferencesCollocationMethod(_fd_eval);
92  edges.addEqualityEdge(edge);
93  }
95  {
96  LeftSumEqualityEdge::Ptr edge = std::make_shared<LeftSumEqualityEdge>(_x_seq[k], _u_seq[block_idx], _dt, nlp_fun.stage_equalities, k);
97  edges.addEqualityEdge(edge);
98 
99  // system dynamics edge
100  FDCollocationEdge::Ptr sys_edge = std::make_shared<FDCollocationEdge>(dynamics, _x_seq[k], _u_seq[block_idx], x_next, _dt);
101  sys_edge->setFiniteDifferencesCollocationMethod(_fd_eval);
102  edges.addEqualityEdge(sys_edge);
103  }
104  else
105  PRINT_ERROR_NAMED("Cost integration rule not implemented");
106  }
107  else
108  {
109  // just the system dynamics edge
110  FDCollocationEdge::Ptr edge = std::make_shared<FDCollocationEdge>(dynamics, _x_seq[k], _u_seq[block_idx], x_next, _dt);
111  edge->setFiniteDifferencesCollocationMethod(_fd_eval);
112  edges.addEqualityEdge(edge);
113  }
114 
115  if (nlp_fun.stage_inequalities && nlp_fun.stage_inequalities->hasIntegralTerms(k))
116  {
118  {
120  std::make_shared<TrapezoidalIntegralInequalityEdge>(_x_seq[k], _u_seq[block_idx], x_next, _dt, nlp_fun.stage_inequalities, k);
121  edges.addInequalityEdge(edge);
122  }
124  {
126  std::make_shared<LeftSumInequalityEdge>(_x_seq[k], _u_seq[block_idx], _dt, nlp_fun.stage_inequalities, k);
127  edges.addInequalityEdge(edge);
128  }
129  else
130  PRINT_ERROR_NAMED("Cost integration rule not implemented");
131  }
132  }
133 
134  // check if we have a separate unfixed final state
135  if (!_xf.isFixed())
136  {
137  // set final state cost
138  BaseEdge::Ptr cost_edge = nlp_fun.getFinalStateCostEdge(n - 1, _xf);
139  if (cost_edge) edges.addObjectiveEdge(cost_edge);
140 
141  // set final state constraint
142  BaseEdge::Ptr constr_edge = nlp_fun.getFinalStateConstraintEdge(n - 1, _xf);
143  if (constr_edge)
144  {
145  if (nlp_fun.final_stage_constraints->isEqualityConstraint())
146  edges.addEqualityEdge(constr_edge);
147  else
148  edges.addInequalityEdge(constr_edge);
149  }
150  }
151 
152  // add control deviation edges for last control
153  cost_terms.clear();
154  eq_terms.clear();
155  ineq_terms.clear();
156  nlp_fun.getFinalControlDeviationEdges(n, _u_ref, _u_seq.back(), _dt, cost_terms, eq_terms, ineq_terms);
157  for (BaseEdge::Ptr& edge : cost_terms) edges.addObjectiveEdge(edge);
158  for (BaseEdge::Ptr& edge : eq_terms) edges.addEqualityEdge(edge);
159  for (BaseEdge::Ptr& edge : ineq_terms) edges.addInequalityEdge(edge);
160 }
161 
162 #ifdef MESSAGE_SUPPORT
163 void FiniteDifferencesGridMoveBlocking::fromMessage(const messages::FiniteDifferencesGridMoveBlocking& message, std::stringstream* issues)
164 {
165  if (message.n() < 2 && issues) *issues << "FiniteDifferencesGridMoveBlocking: Number of states must be greater than or equal 2.\n";
166  if (message.dt() <= 0 && issues) *issues << "FiniteDifferencesGridMoveBlocking: Dt must be greater than 0.0.\n";
167 
168  setNRef(message.n());
169  setDtRef(message.dt());
170  setWarmStart(message.warm_start());
171  setWarmStartShiftU(message.warm_start_shift_u());
172 
173  switch (message.cost_integration_rule())
174  {
175  case messages::FiniteDifferencesGridMoveBlocking::CostIntegrationRule::FiniteDifferencesGridMoveBlocking_CostIntegrationRule_LeftSum:
176  {
178  break;
179  }
180  case messages::FiniteDifferencesGridMoveBlocking::CostIntegrationRule::FiniteDifferencesGridMoveBlocking_CostIntegrationRule_TrapezoidalRule:
181  {
183  break;
184  }
185  default:
186  {
187  PRINT_ERROR_NAMED("FiniteDifferencesGridMoveBlocking: Selected cost integration rule not implemented");
188  }
189  };
190 
191  // fd collocation method
192  // construct object
193  std::string type;
194  util::get_oneof_field_type(message.fd_collocation(), "fd_collocation", type, false);
195  FiniteDifferencesCollocationInterface::Ptr fd_eval = create_from_factory<FiniteDifferencesCollocationInterface>(type);
196  // import parameters
197  if (fd_eval)
198  {
199  fd_eval->fromMessage(message.fd_collocation(), issues);
201  }
202  else
203  {
204  if (issues) *issues << "FiniteDifferencesGridMoveBlocking: unknown finite differences collocation method specified.\n";
205  return;
206  }
207 
208  // Blocking vector
209  if (message.b_size() > getNRef() - 1 && issues)
210  {
211  *issues << "FiniteDifferencesGridMoveBlocking: Cannot have more blocking indices than controls.\n";
212  return;
213  }
214  _blocking_vector = Eigen::Map<const Eigen::VectorXi>(message.b().data(), message.b_size());
215 }
216 
217 void FiniteDifferencesGridMoveBlocking::toMessage(messages::FiniteDifferencesGridMoveBlocking& message) const
218 {
219  message.set_n(getNRef());
220  message.set_dt(getDtRef());
221  message.set_warm_start(_warm_start);
222  message.set_warm_start_shift_u(_warm_start_shift_u);
223 
224  // fd collocation method
225  if (_fd_eval) _fd_eval->fromMessage(*message.mutable_fd_collocation());
226 
227  switch (_cost_integration)
228  {
230  {
231  message.set_cost_integration_rule(
232  messages::FiniteDifferencesGridMoveBlocking::CostIntegrationRule::FiniteDifferencesGridMoveBlocking_CostIntegrationRule_LeftSum);
233  break;
234  }
236  {
237  message.set_cost_integration_rule(messages::FiniteDifferencesGridMoveBlocking::CostIntegrationRule::
238  FiniteDifferencesGridMoveBlocking_CostIntegrationRule_TrapezoidalRule);
239  break;
240  }
241  default:
242  {
243  PRINT_ERROR_NAMED("FiniteDifferencesGridMoveBlocking: Selected cost integration rule not implemented");
244  }
245  };
246 
247  // Blocking vector
248  message.mutable_b()->Resize(_blocking_vector.size(), 0);
249  Eigen::Map<Eigen::VectorXi>(message.mutable_b()->mutable_data(), _blocking_vector.size()) = _blocking_vector;
250 }
251 #endif
252 
253 } // namespace corbo
std::shared_ptr< TrapezoidalIntegralInequalityEdge > Ptr
#define PRINT_ERROR_NAMED(msg)
Definition: console.h:260
std::shared_ptr< LeftSumEqualityEdge > Ptr
BaseEdge::Ptr getFinalStateCostEdge(int k, VectorVertex &xf)
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:94
FinalStageConstraint::Ptr final_stage_constraints
Definition: nlp_functions.h:43
virtual bool isFixed() const
Check if all components are fixed.
StageCost::Ptr stage_cost
Definition: nlp_functions.h:39
std::shared_ptr< LeftSumCostEdge > Ptr
Vertex implementation for scalar values.
Definition: scalar_vertex.h:50
void setFiniteDifferencesCollocationMethod(FiniteDifferencesCollocationInterface::Ptr fd_eval)
std::shared_ptr< FDCollocationEdge > Ptr
std::shared_ptr< TrapezoidalIntegralCostEdge > Ptr
void setCostIntegrationRule(CostIntegrationRule integration)
void getFinalControlDeviationEdges(int n, VectorVertex &u_ref, VectorVertex &u_prev, ScalarVertex &u_prev_dt, std::vector< BaseEdge::Ptr > &cost_edges, std::vector< BaseEdge::Ptr > &eq_edges, std::vector< BaseEdge::Ptr > &ineq_edges)
FiniteDifferencesCollocationInterface::Ptr _fd_eval
void clear() override
Definition: edge_set.cpp:238
std::shared_ptr< LeftSumInequalityEdge > Ptr
void createEdges(NlpFunctions &nlp_fun, OptimizationEdgeSet &edges, SystemDynamicsInterface::Ptr dynamics) override
std::shared_ptr< BaseEdge > Ptr
void addObjectiveEdge(BaseEdge::Ptr edge)
Definition: edge_set.h:118
void clear() override
Clear complete backup container.
void getNonIntegralStageFunctionEdges(int k, VectorVertex &xk, VectorVertex &uk, ScalarVertex &dt, VectorVertex &u_prev, ScalarVertex &u_prev_dt, const StageFunction &stage_fun, std::vector< BaseEdge::Ptr > &edges)
BaseEdge::Ptr getFinalStateConstraintEdge(int k, VectorVertex &xf)
void addEqualityEdge(BaseEdge::Ptr edge)
Definition: edge_set.h:138
Vertex implementation that stores an Eigen::VectorXd (dynamic dimension)
Definition: vector_vertex.h:51
StageInequalityConstraint::Ptr stage_inequalities
Definition: nlp_functions.h:42
std::shared_ptr< TrapezoidalIntegralEqualityDynamicsEdge > Ptr
PlainMatrixType mat * n
Definition: eigenvalues.cpp:41
void addInequalityEdge(BaseEdge::Ptr edge)
Definition: edge_set.h:139
std::shared_ptr< FiniteDifferencesCollocationInterface > Ptr
StageEqualityConstraint::Ptr stage_equalities
Definition: nlp_functions.h:41
std::shared_ptr< SystemDynamicsInterface > Ptr


control_box_rst
Author(s): Christoph Rösmann
autogenerated on Mon Feb 28 2022 22:06:51