bool DiscretizeConstrainedMultiPath(Robot& robot,const MultiPath& path,MultiPath& out,Real xtol) { if(path.settings.contains("resolution")) { //see if the resolution is high enough to just interpolate directly Real res=path.settings.as<Real>("resolution"); if(res <= xtol) { out = path; return true; } } vector<GeneralizedCubicBezierSpline> paths; if(!InterpolateConstrainedMultiPath(robot,path,paths,xtol)) return false; out = path; { out.settings.set("resolution",xtol); out.settings.set("program","DiscretizeConstrainedMultiPath"); } Real tofs = (path.HasTiming() ? path.sections[0].times.front() : 0); for(size_t i=0;i<out.sections.size();i++) { out.sections[i].velocities.resize(0); paths[i].GetPiecewiseLinear(out.sections[i].times,out.sections[i].milestones); //shift section timing Real tscale = (path.HasTiming() ? path.sections[i].times.back()-path.sections[i].times.front() : 1.0) / out.sections[i].times.back(); for(size_t j=0;j<out.sections[i].times.size();j++) out.sections[i].times[j] = tofs + out.sections[i].times[j]*tscale; tofs = out.sections[i].times.back(); } return true; }
void ContactOptimizeMultipath(const char* robfile,const char* pathfile,const char* settingsfile = NULL) { ContactOptimizeSettings settings; if(settingsfile != NULL) { if(!settings.read(settingsfile)) { printf("Unable to read settings file %s\n",settingsfile); return; } } Real xtol=Real(settings["xtol"]); int numdivs = int(settings["numdivs"]); bool ignoreForces = bool(settings["ignoreForces"]); Real torqueRobustness = Real(settings["torqueRobustness"]); Real frictionRobustness = Real(settings["frictionRobustness"]); Real forceRobustness = Real(settings["forceRobustness"]); string outputPath; settings["outputPath"].as(outputPath); Real outputDt = Real(settings["outputDt"]); Robot robot; if(!robot.Load(robfile)) { printf("Unable to load robot file %s\n",robfile); return; } MultiPath path; if(!path.Load(pathfile)) { printf("Unable to load path file %s\n",pathfile); return; } //double check friction for(size_t i=0;i<path.sections.size();i++) { Stance s; path.GetStance(s,i); bool changed = false; int k=0; int numContacts = 0; for(Stance::iterator h=s.begin();h!=s.end();h++,k++) { numContacts += (int)h->second.contacts.size(); for(size_t j=0;j<h->second.contacts.size();j++) if(h->second.contacts[j].kFriction <= 0) { if(!changed) printf("Warning, contact %d of hold %d has invalid friction %g, setting to 0.5\n",j,k,h->second.contacts[j].kFriction); h->second.contacts[j].kFriction = 0.5; changed = true; } } path.SetStance(s,i); if(numContacts == 0 && !ignoreForces && robot.joints[0].type == RobotJoint::Floating) { printf("Warning, no contacts given in stance %d for floating-base robot\n",i); printf("Should set ignoreForces = true in trajopt.settings if you wish\n"); printf("to ignore contact force constraints.\n"); printf("Press enter to continue...\n"); getchar(); } } TimeScaledBezierCurve opttraj; if(ignoreForces) { bool res=GenerateAndTimeOptimizeMultiPath(robot,path,xtol,outputDt); if(!res) { printf("Time optimization failed\n"); return; } Assert(path.HasTiming()); cout<<"Saving dynamically optimized path to "<<outputPath<<endl; ofstream out(outputPath.c_str(),ios::out); for(size_t i=0;i<path.sections.size();i++) { for(size_t j=0;j<path.sections[i].milestones.size();j++) out<<path.sections[i].times[j]<<"\t"<<path.sections[i].milestones[j]<<endl; } out.close(); } else { bool res=ContactOptimizeMultipath(robot,path,xtol, numdivs,opttraj, torqueRobustness, frictionRobustness, forceRobustness); if(!res) { printf("Time optimization failed\n"); return; } RobotCSpace cspace(robot); for(size_t i=0;i<opttraj.path.segments.size();i++) { opttraj.path.segments[i].space = &cspace; opttraj.path.segments[i].manifold = &cspace; } vector<Config> milestones; opttraj.GetDiscretizedPath(outputDt,milestones); cout<<"Saving dynamically optimized path to "<<outputPath<<endl; ofstream out(outputPath.c_str(),ios::out); for(size_t i=0;i<milestones.size();i++) { out<<i*outputDt<<"\t"<<milestones[i]<<endl; } out.close(); printf("Plotting vel/acc constraints to trajopt_plot.csv...\n"); opttraj.Plot("trajopt_plot.csv",robot.velMin,robot.velMax,-1.0*robot.accMax,robot.accMax); } }