Ejemplo n.º 1
0
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);
  }
}
Ejemplo n.º 2
0
int main(int argc,const char** argv)
{
  if(argc < 5) {
    printf("USAGE: timeopt spline limits gridRes dt\n");
    printf("  Optimizes the time scaling of the cubic spline 'spline' under\n");
    printf("  velocity/acceleration limits in the file 'limits'.\n");
    printf("  The time-scaling domain is split into gridRes points.\n");
    printf("  The output trajectory  is a list of time/milestone pairs\n");
    printf("  discretized at timestep dt.\n");
    return 0;
  }
  TimeScaledBezierCurve output;
  {
    ifstream in(argv[1],ios::in);
    if(!output.path.Load(in)) {
      printf("Unable to load spline file %s\n",argv[1]);
      return 1;
    }
  }
  Vector vmin,vmax,amin,amax;
  {
    ifstream in(argv[2],ios::in);
    if(!in) {
      printf("Unable to load limits file %s\n",argv[2]);
      return 1;
    }
    in >> vmin >> vmax >> amin >> amax;
    if(!in) {
      printf("Error loading limits file %s\n",argv[2]);
      return 1;
    }
  }

  for(size_t i=0;i<output.path.segments.size();i++) {
    if(output.path.segments[i].x0.n != output.path.segments[0].x0.n) {
      printf("Invalid milestone size on segment %d: %d vs %d\n",i,output.path.segments[i].x0.n,output.path.segments[0].x0.n);
      return 1;
    }
    if(output.path.segments[i].x1.n != output.path.segments[0].x0.n) {
      printf("Invalid milestone size on segment %d: %d vs %d\n",i,output.path.segments[i].x1.n,output.path.segments[0].x0.n);
      return 1;
    }
    if(output.path.segments[i].x2.n != output.path.segments[0].x0.n) {
      printf("Invalid milestone size on segment %d: %d vs %d\n",i,output.path.segments[i].x2.n,output.path.segments[0].x0.n);
      return 1;
    }
    if(output.path.segments[i].x3.n != output.path.segments[0].x0.n) {
      printf("Invalid milestone size on segment %d: %d vs %d\n",i,output.path.segments[i].x3.n,output.path.segments[0].x0.n);
      return 1;
    }
  }
  if(vmin.n != output.path.segments[0].x0.n) {
    printf("Invalid length of limits: %d vs %d\n",vmin.n,output.path.segments[0].x0.n);
    return 1;
  }
  int gridRes;
  Real dt;
  gridRes = atoi(argv[3]);
  dt = atof(argv[4]);

  if((int)output.path.segments.size() < gridRes) {
    GeneralizedCubicBezierSpline path;
    path.segments.reserve(gridRes+output.path.segments.size());
    path.durations.reserve(gridRes+output.path.segments.size());
    Config xp,vp,xn,vn;
    Real T = output.path.TotalTime();
    for(size_t i=0;i<output.path.segments.size();i++) {
      int n = (int)Ceil(gridRes*(output.path.durations[i]/T));
      if(n <= 0) {
	printf("Error: curve segment %d has nonpositive duration?\n",i);
	return 1;
      }

      //split segment[i] into n pieces
      Real divScale = 1.0/Real(n);
      xp = output.path.segments[i].x0;
      output.path.segments[i].Deriv(0,vp);
      for(int j=0;j<n;j++) {
	Real u2=Real(j+1)/Real(n);
	output.path.segments[i].Eval(u2,xn);
	output.path.segments[i].Deriv(u2,vn);
	path.segments.resize(path.segments.size()+1);
	path.durations.push_back(divScale*output.path.durations[i]);
	path.segments.back().x0 = xp;
	path.segments.back().x3 = xn;
	path.segments.back().SetNaturalTangents(vp*divScale,vn*divScale);
	swap(xp,xn);
	swap(vp,vn);
      }
    }
    output.path = path;
  }

  Timer timer;
  if(!output.OptimizeTimeScaling(vmin,vmax,amin,amax)) {
    printf("Error: OptimizeTimeScaling failed\n");
    return 1;
  }
  Real elapsedTime = timer.ElapsedTime();

  printf("Optimized duration %g, time %g\n",output.EndTime(),elapsedTime);
  vector<Vector> milestones;
  output.GetDiscretizedPath(dt,milestones);
  for(size_t i=0;i<milestones.size();i++)
    cout<<dt*i<<"\t"<<milestones[i]<<endl;;

  printf("Saving time scaling to timeopt_plot.csv\n");
  output.Plot("timeopt_plot.csv",vmin,vmax,amin,amax,1.0/Real(gridRes));
  return 0;
}