1 |
|
|
// Copyright (c) 2014, LAAS-CNRS |
2 |
|
|
// Authors: Steve Tonneau (steve.tonneau@laas.fr) |
3 |
|
|
// |
4 |
|
|
// This file is part of hpp-rbprm. |
5 |
|
|
// hpp-rbprm is free software: you can redistribute it |
6 |
|
|
// and/or modify it under the terms of the GNU Lesser General Public |
7 |
|
|
// License as published by the Free Software Foundation, either version |
8 |
|
|
// 3 of the License, or (at your option) any later version. |
9 |
|
|
// |
10 |
|
|
// hpp-rbprm is distributed in the hope that it will be |
11 |
|
|
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty |
12 |
|
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 |
|
|
// General Lesser Public License for more details. You should have |
14 |
|
|
// received a copy of the GNU Lesser General Public License along with |
15 |
|
|
// hpp-rbprm. If not, see <http://www.gnu.org/licenses/>. |
16 |
|
|
|
17 |
|
|
#include <hpp/core/bi-rrt-planner.hh> |
18 |
|
|
#include <hpp/core/configuration-shooter/uniform.hh> |
19 |
|
|
#include <hpp/core/path-validation/discretized.hh> |
20 |
|
|
#include <hpp/core/problem-solver.hh> |
21 |
|
|
#include <hpp/pinocchio/configuration.hh> |
22 |
|
|
#include <hpp/rbprm/interpolation/com-rrt.hh> |
23 |
|
|
#include <hpp/rbprm/interpolation/interpolation-constraints.hh> |
24 |
|
|
#include <hpp/rbprm/interpolation/limb-rrt.hh> |
25 |
|
|
#include <hpp/rbprm/interpolation/time-constraint-utils.hh> |
26 |
|
|
#include <hpp/rbprm/tools.hh> |
27 |
|
|
#ifdef PROFILE |
28 |
|
|
#include "hpp/rbprm/rbprm-profiler.hh" |
29 |
|
|
#endif |
30 |
|
|
|
31 |
|
|
namespace hpp { |
32 |
|
|
using namespace core; |
33 |
|
|
namespace rbprm { |
34 |
|
|
namespace interpolation { |
35 |
|
|
|
36 |
|
|
void SetComRRTConstraints::operator()(ComRRTHelper &helper, const State &from, |
37 |
|
|
const State &to) const { |
38 |
|
|
CreateContactConstraints<ComRRTHelper>(helper, from, to); |
39 |
|
|
// CreateComConstraint<ComRRTHelper,core::PathPtr_t>(helper, helper.refPath_); |
40 |
|
|
// add postural task to respect the constraint during all the motion but |
41 |
|
|
// greatly increase computation time |
42 |
|
|
// FIXME : can lead to discontinuities ... |
43 |
|
|
/* Configuration_t refConfig = helper.fullbody_->referenceConfig(); |
44 |
|
|
CreatePosturalTaskConstraint<ComRRTHelper,Configuration_t>(helper, |
45 |
|
|
refConfig); helper.proj_->lastIsOptional(true); |
46 |
|
|
helper.proj_->numOptimize(500); |
47 |
|
|
helper.proj_->lastAsCost(true); |
48 |
|
|
helper.proj_->errorThreshold(1e-3);*/ |
49 |
|
|
} |
50 |
|
|
|
51 |
|
|
core::PathPtr_t comRRT(RbPrmFullBodyPtr_t fullbody, |
52 |
|
|
ProblemSolverPtr_t problemSolver, |
53 |
|
|
const PathPtr_t comPath, const State &startState, |
54 |
|
|
const State &nextState, |
55 |
|
|
const std::size_t numOptimizations, |
56 |
|
|
const bool keepExtraDof) { |
57 |
|
|
return comRRT(fullbody, problemSolver->problem(), comPath, startState, |
58 |
|
|
nextState, numOptimizations, keepExtraDof); |
59 |
|
|
} |
60 |
|
|
|
61 |
|
|
core::PathPtr_t comRRT(RbPrmFullBodyPtr_t fullbody, |
62 |
|
|
ProblemPtr_t referenceProblem, const PathPtr_t comPath, |
63 |
|
|
const State &startState, const State &nextState, |
64 |
|
|
const std::size_t numOptimizations, |
65 |
|
|
const bool keepExtraDof) { |
66 |
|
|
hppDout(notice, "Begin interpolation::comRRT."); |
67 |
|
|
// check whether there is a contact variations |
68 |
|
|
std::vector<std::string> variations = nextState.allVariations( |
69 |
|
|
startState, extractEffectorsName(fullbody->GetLimbs())); |
70 |
|
|
core::PathPtr_t guidePath; |
71 |
|
|
T_State states; |
72 |
|
|
states.push_back(startState); |
73 |
|
|
states.push_back(nextState); |
74 |
|
|
T_StateFrame stateFrames; |
75 |
|
|
stateFrames.push_back(std::make_pair(comPath->timeRange().first, startState)); |
76 |
|
|
stateFrames.push_back(std::make_pair(comPath->timeRange().second, nextState)); |
77 |
|
|
hppDout(notice, "comRRT : comPath length : " << comPath->length()); |
78 |
|
|
hppDout(notice, "comRRT : startState : r([" |
79 |
|
|
<< pinocchio::displayConfig(startState.configuration_) |
80 |
|
|
<< "])"); |
81 |
|
|
hppDout(notice, "comRRT : nextState : r([" |
82 |
|
|
<< pinocchio::displayConfig(nextState.configuration_) |
83 |
|
|
<< "])"); |
84 |
|
|
|
85 |
|
|
if (variations.empty()) { |
86 |
|
|
hppDout(notice, "No contact variation, use comRRT."); |
87 |
|
|
std::vector<std::string> fixed = nextState.fixedContacts(startState); |
88 |
|
|
pinocchio::DevicePtr_t device = fullbody->device_->clone(); |
89 |
|
|
/*if(keepExtraDof) |
90 |
|
|
{ |
91 |
|
|
device->setDimensionExtraConfigSpace(device->extraConfigSpace().dimension()+1); |
92 |
|
|
}*/ |
93 |
|
|
core::ConfigProjectorPtr_t proj = |
94 |
|
|
core::ConfigProjector::create(device, "proj", 1e-3, 1000); |
95 |
|
|
core::ProblemPtr_t rootProblem = core::Problem::create(device); |
96 |
|
|
for (std::vector<std::string>::const_iterator cit = fixed.begin(); |
97 |
|
|
cit != fixed.end(); ++cit) { |
98 |
|
|
} |
99 |
|
|
rootProblem->configurationShooter( |
100 |
|
|
core::configurationShooter::Uniform::create(device)); |
101 |
|
|
rootProblem->pathValidation(pathValidation::Discretized::create(0.05)); |
102 |
|
|
core::ConstraintSetPtr_t cSet = |
103 |
|
|
core::ConstraintSet::create(rootProblem->robot(), ""); |
104 |
|
|
cSet->addConstraint(proj); |
105 |
|
|
rootProblem->constraints(cSet); |
106 |
|
|
ConfigurationPtr_t start = |
107 |
|
|
ConfigurationPtr_t(new Configuration_t(startState.configuration_)); |
108 |
|
|
ConfigurationPtr_t end = |
109 |
|
|
ConfigurationPtr_t(new Configuration_t(nextState.configuration_)); |
110 |
|
|
rootProblem->initConfig(start); |
111 |
|
|
BiRRTPlannerPtr_t planner = BiRRTPlanner::create(rootProblem); |
112 |
|
|
ProblemTargetPtr_t target = |
113 |
|
|
problemTarget::GoalConfigurations::create(rootProblem); |
114 |
|
|
rootProblem->target(target); |
115 |
|
|
rootProblem->addGoalConfig(end); |
116 |
|
|
hppDout(notice, "Start solve"); |
117 |
|
|
|
118 |
|
|
guidePath = planner->solve(); |
119 |
|
|
hppDout(notice, "Solve success"); |
120 |
|
|
// return guidePath; |
121 |
|
|
} else { |
122 |
|
|
hppDout(notice, "Contact variations, use limbRRT."); |
123 |
|
|
guidePath = limbRRT(fullbody, referenceProblem, states.begin(), |
124 |
|
|
states.begin() + 1, numOptimizations, 10000); |
125 |
|
|
hppDout(notice, "LimbRRT done."); |
126 |
|
|
} |
127 |
|
|
ComRRTShooterFactory shooterFactory(guidePath); |
128 |
|
|
SetComRRTConstraints constraintFactory; |
129 |
|
|
#ifdef PROFILE |
130 |
|
|
RbPrmProfiler &watch = getRbPrmProfiler(); |
131 |
|
|
watch.start("com_traj"); |
132 |
|
|
#endif |
133 |
|
|
hppDout(notice, "Start interpolateStatesFromPath"); |
134 |
|
|
core::PathPtr_t resPath = |
135 |
|
|
interpolateStatesFromPath<ComRRTHelper, ComRRTShooterFactory, |
136 |
|
|
SetComRRTConstraints>( |
137 |
|
|
fullbody, referenceProblem, shooterFactory, constraintFactory, |
138 |
|
|
comPath, stateFrames.begin(), stateFrames.begin() + 1, |
139 |
|
|
numOptimizations, keepExtraDof, 0.05, 10000); |
140 |
|
|
hppDout(notice, "interpolateStatesFromPath end."); |
141 |
|
|
PathVectorPtr_t pv = HPP_DYNAMIC_PTR_CAST(PathVector, resPath); |
142 |
|
|
if (pv) |
143 |
|
|
hppDout(notice, "end of com-rrt, number of paths in pathVector : " |
144 |
|
|
<< pv->numberPaths()); |
145 |
|
|
#ifdef PROFILE |
146 |
|
|
watch.stop("com_traj"); |
147 |
|
|
#endif |
148 |
|
|
return resPath; |
149 |
|
|
} |
150 |
|
|
|
151 |
|
|
core::PathPtr_t comRRTFromPath(RbPrmFullBodyPtr_t fullbody, |
152 |
|
|
core::ProblemSolverPtr_t problemSolver, |
153 |
|
|
const PathPtr_t comPath, |
154 |
|
|
const PathPtr_t guidePath, |
155 |
|
|
const CIT_StateFrame &startState, |
156 |
|
|
const CIT_StateFrame &endState, |
157 |
|
|
const std::size_t numOptimizations) { |
158 |
|
|
ComRRTShooterFactory shooterFactory(guidePath); |
159 |
|
|
SetComRRTConstraints constraintFactory; |
160 |
|
|
return interpolateStatesFromPath<ComRRTHelper, ComRRTShooterFactory, |
161 |
|
|
SetComRRTConstraints>( |
162 |
|
|
fullbody, problemSolver->problem(), shooterFactory, constraintFactory, |
163 |
|
|
comPath, startState, endState, numOptimizations); |
164 |
|
|
} |
165 |
|
|
|
166 |
|
|
core::Configuration_t projectOnCom(RbPrmFullBodyPtr_t fullbody, |
167 |
|
|
core::ProblemPtr_t referenceProblem, |
168 |
|
|
const State &model, |
169 |
|
|
const fcl::Vec3f &targetCom, bool &success) { |
170 |
|
|
core::PathPtr_t unusedPath(StraightPath::create( |
171 |
|
|
fullbody->device_, model.configuration_, model.configuration_, 0)); |
172 |
|
|
ComRRTShooterFactory unusedFactory(unusedPath); |
173 |
|
|
SetComRRTConstraints constraintFactory; |
174 |
|
|
ComRRTHelper helper(fullbody, unusedFactory, constraintFactory, |
175 |
|
|
referenceProblem, unusedPath, 0.001); |
176 |
|
|
CreateContactConstraints<ComRRTHelper>(helper, model, model); |
177 |
|
|
CreateComConstraint<ComRRTHelper, core::PathPtr_t>(helper, helper.refPath_, |
178 |
|
|
targetCom); |
179 |
|
|
|
180 |
|
|
// Configuration_t refConfig = fullbody->referenceConfig(); |
181 |
|
|
// CreatePosturalTaskConstraint<ComRRTHelper,Configuration_t>(helper, |
182 |
|
|
// refConfig); |
183 |
|
|
// helper.proj_->lastIsOptional(true); |
184 |
|
|
helper.proj_->maxIterations(100); |
185 |
|
|
// helper.proj_->lastAsCost(true); |
186 |
|
|
helper.proj_->errorThreshold(1e-3); |
187 |
|
|
|
188 |
|
|
Configuration_t res(helper.fullBodyDevice_->configSize()); |
189 |
|
|
res.head(model.configuration_.rows()) = model.configuration_; |
190 |
|
|
if (helper.proj_->apply(res)) { |
191 |
|
|
success = true; |
192 |
|
|
/*hppDout(notice,"projection successfull, trying to optimize : "); |
193 |
|
|
CreatePosturalTaskConstraint<ComRRTHelper,ConfigurationPtr_t>(helper, |
194 |
|
|
refConfig); helper.proj_->lastIsOptional(true); |
195 |
|
|
helper.proj_->errorThreshold(1e-3); |
196 |
|
|
hppDout(notice,"before : "<<pinocchio::displayConfig(res)); |
197 |
|
|
bool opSuccess = helper.proj_->optimize(res); |
198 |
|
|
hppDout(notice,"optimize successfull : "<<opSuccess); |
199 |
|
|
hppDout(notice,"after : "<<pinocchio::displayConfig(res));*/ |
200 |
|
|
} else { |
201 |
|
|
success = false; |
202 |
|
|
} |
203 |
|
|
// copy extraDoF from original config : |
204 |
|
|
hppDout(notice, "projectOnCom end : "); |
205 |
|
|
hppDout(notice, "original config : " |
206 |
|
|
<< pinocchio::displayConfig(model.configuration_)); |
207 |
|
|
hppDout(notice, "project config : " << pinocchio::displayConfig(res)); |
208 |
|
|
res.segment((fullbody->device_->configSize() - |
209 |
|
|
fullbody->device_->extraConfigSpace().dimension()), |
210 |
|
|
fullbody->device_->extraConfigSpace().dimension()) = |
211 |
|
|
model.configuration_.tail( |
212 |
|
|
fullbody->device_->extraConfigSpace().dimension()); |
213 |
|
|
hppDout(notice, "project config : " |
214 |
|
|
<< pinocchio::displayConfig(res.head(res.rows() - 1))); |
215 |
|
|
return res.head(res.rows() - 1); |
216 |
|
|
} |
217 |
|
|
|
218 |
|
|
/*void generateOneComPath(const pinocchio::ConfigurationIn_t & from, const |
219 |
|
|
pinocchio::ConfigurationIn_t & to, const pinocchio::ConfigurationIn_t & |
220 |
|
|
initSpeed, const double& acceleration) |
221 |
|
|
{ |
222 |
|
|
|
223 |
|
|
} |
224 |
|
|
|
225 |
|
|
typedef |
226 |
|
|
std::vector<pinocchio::vector_t,Eigen::aligned_allocator<pinocchio::vector_t> > |
227 |
|
|
T_Configuration; core::PathPtr_t generateComPath(pinocchio::DevicePtr_t device, |
228 |
|
|
const T_Configuration& configurations, const std::vector<double>& accelerations, |
229 |
|
|
const pinocchio::value_type dt, const pinocchio::ConfigurationIn_t & initSpeed) |
230 |
|
|
{ |
231 |
|
|
assert(configurations.size() == accelerations.size() +1); |
232 |
|
|
core::PathVectorPtr_t res = core::PathVector::create(device->configSize(), |
233 |
|
|
device->numberDof()); pinocchio::value_type size_step = 1 |
234 |
|
|
/(pinocchio::value_type)(positions.size()); pinocchio::value_type u = 0.; |
235 |
|
|
CIT_Configuration pit = positions.begin(); |
236 |
|
|
pinocchio::Configuration_t previous = addRotation(pit, 0., q1, q2, ref), |
237 |
|
|
current; |
238 |
|
|
++pit; |
239 |
|
|
for(;pit != positions.end()-1; ++pit, u+=size_step) |
240 |
|
|
{ |
241 |
|
|
current = addRotation(pit, u, q1, q2, ref); |
242 |
|
|
res->appendPath(makePath(device,problem, previous, current)); |
243 |
|
|
previous = current; |
244 |
|
|
} |
245 |
|
|
// last configuration is exactly q2 |
246 |
|
|
current = addRotation(pit, 1., q1, q2, ref); |
247 |
|
|
res->appendPath(makePath(device,problem, previous, current)); |
248 |
|
|
return res; |
249 |
|
|
|
250 |
|
|
}*/ |
251 |
|
|
} // namespace interpolation |
252 |
|
|
} // namespace rbprm |
253 |
|
|
} // namespace hpp |