nodes_variables_phase_based.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_variables_phase_based.h>
00031 #include <towr/variables/cartesian_dimensions.h>
00032 
00033 #include <iostream>
00034 
00035 namespace towr {
00036 
00037 
00038 std::vector<NodesVariablesPhaseBased::PolyInfo>
00039 BuildPolyInfos (int phase_count, bool first_phase_constant,
00040                 int n_polys_in_changing_phase)
00041 {
00042   using PolyInfo = NodesVariablesPhaseBased::PolyInfo;
00043   std::vector<PolyInfo> polynomial_info;
00044 
00045   bool phase_constant = first_phase_constant;
00046 
00047   for (int i=0; i<phase_count; ++i) {
00048     if (phase_constant)
00049       polynomial_info.push_back(PolyInfo(i,0,1, true));
00050     else
00051       for (int j=0; j<n_polys_in_changing_phase; ++j)
00052         polynomial_info.push_back(PolyInfo(i,j,n_polys_in_changing_phase, false));
00053 
00054     phase_constant = !phase_constant; // constant and non-constant phase alternate
00055   }
00056 
00057   return polynomial_info;
00058 }
00059 
00060 NodesVariablesPhaseBased::NodesVariablesPhaseBased (int phase_count,
00061                                                     bool first_phase_constant,
00062                                                     const std::string& name,
00063                                                     int n_polys_in_changing_phase)
00064     :NodesVariables(name)
00065 {
00066   polynomial_info_ = BuildPolyInfos(phase_count, first_phase_constant, n_polys_in_changing_phase);
00067 
00068   n_dim_ = k3D;
00069   int n_nodes = polynomial_info_.size()+1;
00070   nodes_  = std::vector<Node>(n_nodes, Node(n_dim_));
00071 }
00072 
00073 NodesVariablesPhaseBased::VecDurations
00074 NodesVariablesPhaseBased::ConvertPhaseToPolyDurations(const VecDurations& phase_durations) const
00075 {
00076   VecDurations poly_durations;
00077 
00078   for (int i=0; i<GetPolynomialCount(); ++i) {
00079     auto info = polynomial_info_.at(i);
00080     poly_durations.push_back(phase_durations.at(info.phase_)/info.n_polys_in_phase_);
00081   }
00082 
00083   return poly_durations;
00084 }
00085 
00086 double
00087 NodesVariablesPhaseBased::GetDerivativeOfPolyDurationWrtPhaseDuration (int poly_id) const
00088 {
00089   int n_polys_in_phase = polynomial_info_.at(poly_id).n_polys_in_phase_;
00090   return 1./n_polys_in_phase;
00091 }
00092 
00093 int
00094 NodesVariablesPhaseBased::GetNumberOfPrevPolynomialsInPhase(int poly_id) const
00095 {
00096   return polynomial_info_.at(poly_id).poly_in_phase_;
00097 }
00098 
00099 bool
00100 NodesVariablesPhaseBased::IsConstantNode (int node_id) const
00101 {
00102   bool is_constant = false;
00103 
00104   // node is considered constant if either left or right polynomial
00105   // belongs to a constant phase
00106   for (int poly_id : GetAdjacentPolyIds(node_id))
00107     if (IsInConstantPhase(poly_id))
00108       is_constant = true;
00109 
00110   return is_constant;
00111 }
00112 
00113 bool
00114 NodesVariablesPhaseBased::IsInConstantPhase(int poly_id) const
00115 {
00116   return polynomial_info_.at(poly_id).is_constant_;
00117 }
00118 
00119 NodesVariablesPhaseBased::NodeIds
00120 NodesVariablesPhaseBased::GetIndicesOfNonConstantNodes() const
00121 {
00122   NodeIds node_ids;
00123 
00124   for (int id=0; id<GetNodes().size(); ++id)
00125     if (!IsConstantNode(id))
00126       node_ids.push_back(id);
00127 
00128   return node_ids;
00129 }
00130 
00131 int
00132 NodesVariablesPhaseBased::GetPhase (int node_id) const
00133 {
00134   assert(!IsConstantNode(node_id)); // because otherwise it has two phases
00135 
00136   int poly_id = GetAdjacentPolyIds(node_id).front();
00137   return polynomial_info_.at(poly_id).phase_;
00138 }
00139 
00140 int
00141 NodesVariablesPhaseBased::GetPolyIDAtStartOfPhase (int phase) const
00142 {
00143   int poly_id=0;
00144   for (int i=0; i<polynomial_info_.size(); ++i)
00145     if (polynomial_info_.at(i).phase_ == phase)
00146       return i;
00147 }
00148 
00149 Eigen::Vector3d
00150 NodesVariablesPhaseBased::GetValueAtStartOfPhase (int phase) const
00151 {
00152   int node_id = GetNodeIDAtStartOfPhase(phase);
00153   return GetNodes().at(node_id).p();
00154 }
00155 
00156 int
00157 NodesVariablesPhaseBased::GetNodeIDAtStartOfPhase (int phase) const
00158 {
00159   int poly_id=GetPolyIDAtStartOfPhase(phase);
00160   return GetNodeId(poly_id, Side::Start);
00161 }
00162 
00163 std::vector<int>
00164 NodesVariablesPhaseBased::GetAdjacentPolyIds (int node_id) const
00165 {
00166   std::vector<int> poly_ids;
00167   int last_node_id = GetNodes().size()-1;
00168 
00169   if (node_id==0)
00170     poly_ids.push_back(0);
00171   else if (node_id==last_node_id)
00172     poly_ids.push_back(last_node_id-1);
00173   else {
00174     poly_ids.push_back(node_id-1);
00175     poly_ids.push_back(node_id);
00176   }
00177 
00178   return poly_ids;
00179 }
00180 
00181 NodesVariablesPhaseBased::PolyInfo::PolyInfo(int phase, int poly_id_in_phase,
00182                                int num_polys_in_phase, bool is_constant)
00183     :phase_(phase),
00184      poly_in_phase_(poly_id_in_phase),
00185      n_polys_in_phase_(num_polys_in_phase),
00186      is_constant_(is_constant)
00187 {
00188 }
00189 
00190 void
00191 NodesVariablesPhaseBased::SetNumberOfVariables(int n_variables)
00192 {
00193   bounds_ = VecBound(n_variables, ifopt::NoBound);
00194   SetRows(n_variables);
00195 }
00196 
00197 NodesVariablesEEMotion::NodesVariablesEEMotion(int phase_count,
00198                                                bool is_in_contact_at_start,
00199                                                const std::string& name,
00200                                                int n_polys_in_changing_phase)
00201     :NodesVariablesPhaseBased(phase_count,
00202                               is_in_contact_at_start, // contact phase for motion is constant
00203                               name,
00204                               n_polys_in_changing_phase)
00205 {
00206   index_to_node_value_info_ = GetPhaseBasedEEParameterization();
00207   SetNumberOfVariables(index_to_node_value_info_.size());
00208 }
00209 
00210 NodesVariablesEEForce::OptIndexMap
00211 NodesVariablesEEMotion::GetPhaseBasedEEParameterization ()
00212 {
00213   OptIndexMap index_map;
00214 
00215   int idx = 0; // index in variables set
00216   for (int node_id=0; node_id<nodes_.size(); ++node_id) {
00217     // swing node:
00218     if (!IsConstantNode(node_id)) {
00219       for (int dim=0; dim<GetDim(); ++dim) {
00220         // intermediate way-point position of swing motion are optimized
00221         index_map[idx++].push_back(NodeValueInfo(node_id, kPos, dim));
00222 
00223         // velocity in vertical direction fixed to zero and not optimized.
00224         // Since we often choose two polynomials per swing-phase, this restricts
00225         // the swing to have reached it's extreme at half-time and creates
00226         // smoother stepping motions.
00227         if (dim == Z)
00228           nodes_.at(node_id).at(kVel).z() = 0.0;
00229         else
00230           // velocity in x,y dimension during swing fully optimized.
00231           index_map[idx++].push_back(NodeValueInfo(node_id, kVel, dim));
00232       }
00233     }
00234     // stance node (next one will also be stance, so handle that one too):
00235     else {
00236       // ensure that foot doesn't move by not even optimizing over velocities
00237       nodes_.at(node_id).at(kVel).setZero();
00238       nodes_.at(node_id+1).at(kVel).setZero();
00239 
00240       // position of foot is still an optimization variable used for
00241       // both start and end node of that polynomial
00242       for (int dim=0; dim<GetDim(); ++dim) {
00243         index_map[idx].push_back(NodeValueInfo(node_id,   kPos, dim));
00244         index_map[idx].push_back(NodeValueInfo(node_id+1, kPos, dim));
00245         idx++;
00246       }
00247 
00248       node_id += 1; // already added next constant node, so skip
00249     }
00250   }
00251 
00252   return index_map;
00253 }
00254 
00255 NodesVariablesEEForce::NodesVariablesEEForce(int phase_count,
00256                                               bool is_in_contact_at_start,
00257                                               const std::string& name,
00258                                               int n_polys_in_changing_phase)
00259     :NodesVariablesPhaseBased(phase_count,
00260                               !is_in_contact_at_start, // contact phase for force is non-constant
00261                               name,
00262                               n_polys_in_changing_phase)
00263 {
00264   index_to_node_value_info_ = GetPhaseBasedEEParameterization();
00265   SetNumberOfVariables(index_to_node_value_info_.size());
00266 }
00267 
00268 NodesVariablesEEForce::OptIndexMap
00269 NodesVariablesEEForce::GetPhaseBasedEEParameterization ()
00270 {
00271   OptIndexMap index_map;
00272 
00273   int idx = 0; // index in variables set
00274   for (int id=0; id<nodes_.size(); ++id) {
00275     // stance node:
00276     // forces can be created during stance, so these nodes are optimized over.
00277     if (!IsConstantNode(id)) {
00278       for (int dim=0; dim<GetDim(); ++dim) {
00279         index_map[idx++].push_back(NodeValueInfo(id, kPos, dim));
00280         index_map[idx++].push_back(NodeValueInfo(id, kVel, dim));
00281       }
00282     }
00283     // swing node (next one will also be swing, so handle that one too)
00284     else {
00285       // forces can't exist during swing phase, so no need to be optimized
00286       // -> all node values simply set to zero.
00287       nodes_.at(id).at(kPos).setZero();
00288       nodes_.at(id+1).at(kPos).setZero();
00289 
00290       nodes_.at(id).at(kVel).setZero();
00291       nodes_.at(id+1).at(kVel).setZero();
00292 
00293       id += 1; // already added next constant node, so skip
00294     }
00295   }
00296 
00297   return index_map;
00298 }
00299 
00300 } /* namespace towr */


towr
Author(s): Alexander W. Winkler
autogenerated on Mon Apr 15 2019 02:42:32