00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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;
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
00105
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));
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,
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;
00216 for (int node_id=0; node_id<nodes_.size(); ++node_id) {
00217
00218 if (!IsConstantNode(node_id)) {
00219 for (int dim=0; dim<GetDim(); ++dim) {
00220
00221 index_map[idx++].push_back(NodeValueInfo(node_id, kPos, dim));
00222
00223
00224
00225
00226
00227 if (dim == Z)
00228 nodes_.at(node_id).at(kVel).z() = 0.0;
00229 else
00230
00231 index_map[idx++].push_back(NodeValueInfo(node_id, kVel, dim));
00232 }
00233 }
00234
00235 else {
00236
00237 nodes_.at(node_id).at(kVel).setZero();
00238 nodes_.at(node_id+1).at(kVel).setZero();
00239
00240
00241
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;
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,
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;
00274 for (int id=0; id<nodes_.size(); ++id) {
00275
00276
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
00284 else {
00285
00286
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;
00294 }
00295 }
00296
00297 return index_map;
00298 }
00299
00300 }