nodes.cc
Go to the documentation of this file.
00001 /******************************************************************************
00002 Copyright (c) 2018, Alexander W. Winkler. All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions are met:
00006 
00007 * Redistributions of source code must retain the above copyright notice, this
00008   list of conditions and the following disclaimer.
00009 
00010 * Redistributions in binary form must reproduce the above copyright notice,
00011   this list of conditions and the following disclaimer in the documentation
00012   and/or other materials provided with the distribution.
00013 
00014 * Neither the name of the copyright holder nor the names of its
00015   contributors may be used to endorse or promote products derived from
00016   this software without specific prior written permission.
00017 
00018 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00019 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00021 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00022 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00023 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00024 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00025 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00027 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028 ******************************************************************************/
00029 
00030 #include <towr/variables/nodes.h>
00031 
00032 
00033 namespace towr {
00034 
00035 
00036 Nodes::Nodes (int n_dim, const std::string& name)
00037     : VariableSet(kSpecifyLater, name)
00038 {
00039   n_dim_ = n_dim;
00040 }
00041 
00042 void
00043 Nodes::InitMembers(int n_nodes, int n_variables)
00044 {
00045   nodes_  = std::vector<Node>(n_nodes, Node(n_dim_));
00046   bounds_ = VecBound(n_variables, ifopt::NoBound);
00047   SetRows(n_variables);
00048 }
00049 
00050 void
00051 Nodes::InitializeNodesTowardsGoal(const VectorXd& initial_pos,
00052                                const VectorXd& final_pos,
00053                                double t_total)
00054 {
00055   VectorXd dp = final_pos-initial_pos;
00056   VectorXd average_velocity = dp/t_total;
00057   int num_nodes = nodes_.size();
00058   for (int i=0; i<nodes_.size(); ++i) {
00059     Node n(n_dim_);
00060     n.at(kPos) = initial_pos + i/static_cast<double>(num_nodes-1)*dp;
00061     n.at(kVel) = average_velocity;
00062     nodes_.at(i) = n;
00063   }
00064 }
00065 
00066 Nodes::IndexInfo::IndexInfo(int node_id, Dx deriv, int node_dim)
00067 {
00068   node_id_    = node_id;
00069   node_deriv_ = deriv;
00070   node_dim_   = node_dim;
00071 }
00072 
00073 int
00074 Nodes::Index(int node_id, Dx deriv, int node_dim) const
00075 {
00076   return Index(IndexInfo(node_id, deriv, node_dim));
00077 }
00078 
00079 int
00080 Nodes::Index(const IndexInfo& n) const
00081 {
00082   // could also cache this as map for more efficiency, but adding complexity
00083   for (int idx=0; idx<GetRows(); ++idx)
00084     for ( IndexInfo node_info : GetNodeInfoAtOptIndex(idx))
00085       if ( node_info == n )
00086         return idx;
00087 
00088   assert(false); // index representing these quantities doesn't exist
00089 }
00090 
00091 // reverse of the above
00092 std::vector<Nodes::IndexInfo>
00093 Nodes::GetNodeInfoAtOptIndex (int idx) const
00094 {
00095   std::vector<IndexInfo> nodes;
00096 
00097   // always two consecutive node pairs are equal
00098   int n_opt_values_per_node_ = 2*n_dim_;
00099   int internal_id = idx%n_opt_values_per_node_; // 0...6 (p.x, p.y, p.z, v.x, v.y. v.z)
00100 
00101   IndexInfo node;
00102   node.node_deriv_ = internal_id<n_dim_? kPos : kVel;
00103   node.node_dim_   = internal_id%n_dim_;
00104   node.node_id_    = std::floor(idx/n_opt_values_per_node_);
00105 
00106   nodes.push_back(node);
00107 
00108   return nodes;
00109 }
00110 
00111 Eigen::VectorXd
00112 Nodes::GetValues () const
00113 {
00114   VectorXd x(GetRows());
00115 
00116   for (int idx=0; idx<x.rows(); ++idx)
00117     for (auto info : GetNodeInfoAtOptIndex(idx))
00118       x(idx) = nodes_.at(info.node_id_).at(info.node_deriv_)(info.node_dim_);
00119 
00120   return x;
00121 }
00122 
00123 void
00124 Nodes::SetVariables (const VectorXd& x)
00125 {
00126   for (int idx=0; idx<x.rows(); ++idx)
00127     for (auto info : GetNodeInfoAtOptIndex(idx))
00128       nodes_.at(info.node_id_).at(info.node_deriv_)(info.node_dim_) = x(idx);
00129 
00130   UpdateObservers();
00131 }
00132 
00133 void
00134 Nodes::UpdateObservers() const
00135 {
00136   for (auto& o : observers_)
00137     o->UpdateNodes();
00138 }
00139 
00140 void
00141 Nodes::AddObserver(ObserverPtr const o)
00142 {
00143    observers_.push_back(o);
00144 }
00145 
00146 int
00147 Nodes::GetNodeId (int poly_id, Side side)
00148 {
00149   return poly_id + side;
00150 }
00151 
00152 const std::vector<Node>
00153 Nodes::GetBoundaryNodes(int poly_id) const
00154 {
00155   std::vector<Node> nodes;
00156   nodes.push_back(nodes_.at(GetNodeId(poly_id, Side::Start)));
00157   nodes.push_back(nodes_.at(GetNodeId(poly_id, Side::End)));
00158   return nodes;
00159 }
00160 
00161 int
00162 Nodes::GetDim() const
00163 {
00164   return n_dim_;
00165 }
00166 
00167 int
00168 Nodes::GetPolynomialCount() const
00169 {
00170   return nodes_.size() - 1;
00171 }
00172 
00173 Nodes::VecBound
00174 Nodes::GetBounds () const
00175 {
00176   return bounds_;
00177 }
00178 
00179 const std::vector<Node>
00180 Nodes::GetNodes() const
00181 {
00182   return nodes_;
00183 }
00184 
00185 void
00186 Nodes::AddBounds(int node_id, Dx deriv,
00187                          const std::vector<int>& dimensions,
00188                          const VectorXd& val)
00189 {
00190   for (auto dim : dimensions)
00191     AddBound(IndexInfo(node_id, deriv, dim), val(dim));
00192 }
00193 
00194 void
00195 Nodes::AddBound (const IndexInfo& node_info, double val)
00196 {
00197   for (int idx=0; idx<GetRows(); ++idx)
00198     for (auto info : GetNodeInfoAtOptIndex(idx))
00199       if (info == node_info)
00200         bounds_.at(idx) = ifopt::Bounds(val, val);
00201 }
00202 
00203 void
00204 Nodes::AddStartBound (Dx d,
00205                            const std::vector<int>& dimensions,
00206                            const VectorXd& val)
00207 {
00208   AddBounds(0, d, dimensions, val);
00209 }
00210 
00211 void
00212 Nodes::AddFinalBound (Dx deriv,
00213                            const std::vector<int>& dimensions,
00214                            const VectorXd& val)
00215 {
00216   AddBounds(nodes_.size()-1, deriv, dimensions, val);
00217 }
00218 
00219 int
00220 Nodes::IndexInfo::operator==(const IndexInfo& right) const
00221 {
00222   return (node_id_    == right.node_id_)
00223       && (node_deriv_ == right.node_deriv_)
00224       && (node_dim_   == right.node_dim_);
00225 };
00226 
00227 } /* namespace towr */


towr_core
Author(s): Alexander W. Winkler
autogenerated on Mon Apr 9 2018 03:12:44