finite_differences_grid.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: Christoph Rösmann
23  *********************************************************************/
24 
26 
28 
30 #include <corbo-core/console.h>
31 
32 #include <algorithm>
33 #include <cmath>
34 #include <memory>
35 
36 namespace corbo {
37 
39 {
40  assert(isValid());
41 
42  // clear edges first
43  // TODO(roesmann): we could implement a more efficient strategy without recreating the whole edgeset everytime
44  edges.clear();
45 
46  int n = getN();
47 
48  std::vector<BaseEdge::Ptr> cost_terms, eq_terms, ineq_terms;
49  for (int k = 0; k < n - 1; ++k)
50  {
51  VectorVertex& x_next = (k < n - 2) ? _x_seq[k + 1] : _xf;
52  VectorVertex& u_prev = (k > 0) ? _u_seq[k - 1] : _u_prev;
53  ScalarVertex& dt_prev = (k > 0) ? _dt : _u_prev_dt;
54 
55  cost_terms.clear();
56  eq_terms.clear();
57  ineq_terms.clear();
58  nlp_fun.getNonIntegralStageFunctionEdges(k, _x_seq[k], _u_seq[k], _dt, u_prev, dt_prev, cost_terms, eq_terms, ineq_terms);
59  for (BaseEdge::Ptr& edge : cost_terms) edges.addObjectiveEdge(edge);
60  for (BaseEdge::Ptr& edge : eq_terms) edges.addEqualityEdge(edge);
61  for (BaseEdge::Ptr& edge : ineq_terms) edges.addInequalityEdge(edge);
62 
63  if (nlp_fun.stage_cost && nlp_fun.stage_cost->hasIntegralTerms(k))
64  {
66  {
68  std::make_shared<TrapezoidalIntegralCostEdge>(_x_seq[k], _u_seq[k], x_next, _dt, nlp_fun.stage_cost, k);
69  edges.addObjectiveEdge(edge);
70  }
72  {
73  LeftSumCostEdge::Ptr edge = std::make_shared<LeftSumCostEdge>(_x_seq[k], _u_seq[k], _dt, nlp_fun.stage_cost, k);
74  edges.addObjectiveEdge(edge);
75  }
76  else
77  PRINT_ERROR_NAMED("Cost integration rule not implemented");
78  }
79 
80  if (nlp_fun.stage_equalities && nlp_fun.stage_equalities->hasIntegralTerms(k))
81  {
83  {
84  TrapezoidalIntegralEqualityDynamicsEdge::Ptr edge = std::make_shared<TrapezoidalIntegralEqualityDynamicsEdge>(
85  dynamics, _x_seq[k], _u_seq[k], x_next, _dt, nlp_fun.stage_equalities, k);
86  edge->setFiniteDifferencesCollocationMethod(_fd_eval);
87  edges.addEqualityEdge(edge);
88  }
90  {
91  LeftSumEqualityEdge::Ptr edge = std::make_shared<LeftSumEqualityEdge>(_x_seq[k], _u_seq[k], _dt, nlp_fun.stage_equalities, k);
92  edges.addEqualityEdge(edge);
93 
94  // system dynamics edge
95  FDCollocationEdge::Ptr sys_edge = std::make_shared<FDCollocationEdge>(dynamics, _x_seq[k], _u_seq[k], x_next, _dt);
96  sys_edge->setFiniteDifferencesCollocationMethod(_fd_eval);
97  edges.addEqualityEdge(sys_edge);
98  }
99  else
100  PRINT_ERROR_NAMED("Cost integration rule not implemented");
101  }
102  else
103  {
104  // just the system dynamics edge
105  FDCollocationEdge::Ptr edge = std::make_shared<FDCollocationEdge>(dynamics, _x_seq[k], _u_seq[k], x_next, _dt);
106  edge->setFiniteDifferencesCollocationMethod(_fd_eval);
107  edges.addEqualityEdge(edge);
108  }
109 
110  if (nlp_fun.stage_inequalities && nlp_fun.stage_inequalities->hasIntegralTerms(k))
111  {
113  {
115  std::make_shared<TrapezoidalIntegralInequalityEdge>(_x_seq[k], _u_seq[k], x_next, _dt, nlp_fun.stage_inequalities, k);
116  edges.addInequalityEdge(edge);
117  }
119  {
120  LeftSumInequalityEdge::Ptr edge = std::make_shared<LeftSumInequalityEdge>(_x_seq[k], _u_seq[k], _dt, nlp_fun.stage_inequalities, k);
121  edges.addInequalityEdge(edge);
122  }
123  else
124  PRINT_ERROR_NAMED("Cost integration rule not implemented");
125  }
126  }
127 
128  // check if we have a separate unfixed final state
129  if (!_xf.isFixed())
130  {
131  // set final state cost
132  BaseEdge::Ptr cost_edge = nlp_fun.getFinalStateCostEdge(n - 1, _xf);
133  if (cost_edge) edges.addObjectiveEdge(cost_edge);
134 
135  // set final state constraint
136  BaseEdge::Ptr constr_edge = nlp_fun.getFinalStateConstraintEdge(n - 1, _xf);
137  if (constr_edge)
138  {
139  if (nlp_fun.final_stage_constraints->isEqualityConstraint())
140  edges.addEqualityEdge(constr_edge);
141  else
142  edges.addInequalityEdge(constr_edge);
143  }
144  }
145 
146  // add control deviation edges for last control
147  cost_terms.clear();
148  eq_terms.clear();
149  ineq_terms.clear();
150  nlp_fun.getFinalControlDeviationEdges(n, _u_ref, _u_seq.back(), _dt, cost_terms, eq_terms, ineq_terms);
151  for (BaseEdge::Ptr& edge : cost_terms) edges.addObjectiveEdge(edge);
152  for (BaseEdge::Ptr& edge : eq_terms) edges.addEqualityEdge(edge);
153  for (BaseEdge::Ptr& edge : ineq_terms) edges.addInequalityEdge(edge);
154 }
155 
156 #ifdef MESSAGE_SUPPORT
157 void FiniteDifferencesGrid::fromMessage(const messages::FiniteDifferencesGrid& message, std::stringstream* issues)
158 {
159  if (message.n() < 2 && issues) *issues << "FiniteDifferencesGrid: Number of states must be greater than or equal 2.\n";
160  if (message.dt() <= 0 && issues) *issues << "FiniteDifferencesGrid: Dt must be greater than 0.0.\n";
161 
162  setNRef(message.n());
163  setDtRef(message.dt());
164  setWarmStart(message.warm_start());
165 
166  switch (message.cost_integration_rule())
167  {
168  case messages::FiniteDifferencesGrid::CostIntegrationRule::FiniteDifferencesGrid_CostIntegrationRule_LeftSum:
169  {
171  break;
172  }
173  case messages::FiniteDifferencesGrid::CostIntegrationRule::FiniteDifferencesGrid_CostIntegrationRule_TrapezoidalRule:
174  {
176  break;
177  }
178  default:
179  {
180  PRINT_ERROR_NAMED("Selected cost integration rule not implemented");
181  }
182  };
183 
184  // fd collocation method
185  // construct object
186  std::string type;
187  util::get_oneof_field_type(message.fd_collocation(), "fd_collocation", type, false);
188  FiniteDifferencesCollocationInterface::Ptr fd_eval = create_from_factory<FiniteDifferencesCollocationInterface>(type);
189  // import parameters
190  if (fd_eval)
191  {
192  fd_eval->fromMessage(message.fd_collocation(), issues);
194  }
195  else
196  {
197  if (issues) *issues << "FiniteDifferencesGrid: unknown finite differences collocation method specified.\n";
198  return;
199  }
200 }
201 
202 void FiniteDifferencesGrid::toMessage(messages::FiniteDifferencesGrid& message) const
203 {
204  message.set_n(getNRef());
205  message.set_dt(getDtRef());
206  message.set_warm_start(_warm_start);
207 
208  // fd collocation method
209  if (_fd_eval) _fd_eval->fromMessage(*message.mutable_fd_collocation());
210 
211  switch (_cost_integration)
212  {
214  {
215  message.set_cost_integration_rule(
216  messages::FiniteDifferencesGrid::CostIntegrationRule::FiniteDifferencesGrid_CostIntegrationRule_LeftSum);
217  break;
218  }
220  {
221  message.set_cost_integration_rule(
222  messages::FiniteDifferencesGrid::CostIntegrationRule::FiniteDifferencesGrid_CostIntegrationRule_TrapezoidalRule);
223  break;
224  }
225  default:
226  {
227  PRINT_ERROR_NAMED("Selected cost integration rule not implemented");
228  }
229  };
230 }
231 #endif
232 
233 } // 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)
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 createEdges(NlpFunctions &nlp_fun, OptimizationEdgeSet &edges, SystemDynamicsInterface::Ptr dynamics) override
void clear() override
Definition: edge_set.cpp:238
std::shared_ptr< LeftSumInequalityEdge > Ptr
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