예제 #1
0
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;
}
예제 #2
0
void EvaluateMultiPath(Robot& robot,const MultiPath& path,Real t,Config& q,Real xtol,Real contactol,int numIKIters)
{
  RobotCSpace space(robot);;
  RobotGeodesicManifold manifold(robot);
  GeneralizedCubicBezierCurve curve(&space,&manifold);
  Real duration,param;
  int seg=path.Evaluate(t,curve,duration,param,MultiPath::InterpLinear);
  if(seg < 0) seg = 0;
  if(seg >= path.sections.size()) seg = (int)path.sections.size()-1;
  curve.Eval(param,q);

  //solve for constraints
  bool solveIK = false;
  if(!path.settings.contains("resolution"))
    solveIK = true;
  else {
    Real res = path.settings.as<Real>("resolution");
    if(res > xtol) solveIK=true;
  }
  if(solveIK) {
    vector<IKGoal> ik;
    path.GetIKProblem(ik,seg);
    if(!ik.empty()) {
      swap(q,robot.q);
      robot.UpdateFrames();

      int iters=numIKIters;
      bool res=SolveIK(robot,ik,contactol,iters,0);
      if(!res) printf("Warning, couldn't solve IK problem at sec %d, time %g\n",seg,t);
      swap(q,robot.q);
    }
  }
}
예제 #3
0
    Real EuropeanMultiPathPricer::operator()(const MultiPath& multiPath)
                                                                      const {
        Size n = multiPath.pathSize();
        QL_REQUIRE(n>0, "the path cannot be empty");

        Size numAssets = multiPath.assetNumber();
        QL_REQUIRE(numAssets>0, "there must be some paths");

        Size j;
        // calculate the final price of each asset
        Array finalPrice(numAssets, 0.0);
        for (j = 0; j < numAssets; j++)
            finalPrice[j] = multiPath[j].back();
        return (*payoff_)(finalPrice) * discount_;
    }
예제 #4
0
Real EverestMultiPathPricer::operator()(const MultiPath& multiPath) const {

    Size n = multiPath.pathSize();
    QL_REQUIRE(n>0, "the path cannot be empty");

    Size numAssets = multiPath.assetNumber();
    QL_REQUIRE(numAssets>0, "there must be some paths");

    // We search the yield min
    Real minYield = multiPath[0].back() / multiPath[0].front() - 1.0;
    for (Size j=1; j<numAssets; ++j) {
        Rate yield = multiPath[j].back() / multiPath[j].front() - 1.0;
        minYield = std::min(minYield, yield);
    }
    return (1.0 + minYield + guarantee_) * notional_ * discount_;
}
    inline Real EuropeanHestonPathPricer::operator()(
                                           const MultiPath& multiPath) const {
        const Path& path = multiPath[0];
        const Size n = multiPath.pathSize();
        QL_REQUIRE(n>0, "the path cannot be empty");

        return payoff_(path.back()) * discount_;
    }
예제 #6
0
    Real PagodaMultiPathPricer::operator()(const MultiPath& multiPath) const {

        Size numAssets = multiPath.assetNumber();
        Size numSteps = multiPath.pathSize();

        Real averagePerformance = 0.0;
        for (Size i = 1; i < numSteps; i++) {
            for (Size j = 0; j < numAssets; j++) {
                averagePerformance +=
                    multiPath[j].front() *
                    (multiPath[j][i]/multiPath[j][i-1] - 1.0);
            }
        }
        averagePerformance /= numAssets;

        return discount_ * fraction_
            * std::max<Real>(0.0, std::min(roof_, averagePerformance));
    }
예제 #7
0
bool ContactTimeScaling::Check(const MultiPath& path)
{
  Robot& robot = cspace.robot;
  //test at the colocation points
  Assert(traj.timeScaling.times.size()==paramDivs.size());
  Vector x,dx,ddx;
  bool feasible = true;
  for(size_t i=0;i<paramDivs.size();i++) {
    int seg=paramSections[i];
    Real t=traj.timeScaling.times[i];
    traj.Eval(t,x);
    traj.Deriv(t,dx);
    traj.Accel(t,ddx);

    for(int j=0;j<dx.n;j++)
      if(Abs(dx[j]) > robot.velMax[j]*(1+Epsilon)) {
	printf("Vel at param %d (time %g/%g) is infeasible\n",i,t,traj.timeScaling.times.back());
	printf("   |%g| > %g  at link %s\n",dx[j],robot.velMax[j],robot.LinkName(j).c_str());
	feasible = false;
      }

    for(int j=0;j<ddx.n;j++)
      if(Abs(ddx[j]) > robot.accMax[j]*(1+Epsilon)) {
	printf("Acc at param %d (time %g/%g) is infeasible\n",i,t,traj.timeScaling.times.back());
	printf("   |%g| > %g  at link %s\n",ddx[j],robot.accMax[j],robot.LinkName(j).c_str());
	feasible = false;
      }


    ContactFormation formation;
    Stance stance;
    path.GetStance(stance,seg);
    ToContactFormation(stance,formation);
    if(formation.contacts.empty()) continue;

    robot.UpdateConfig(x);
    robot.dq = dx;
    TorqueSolver solver(robot,formation);
    solver.SetGravity(Vector3(0,0,-9.8));
    solver.SetDynamics(ddx);
    bool res=solver.Solve();
    if(!res) {
      printf("TorqueSolver was not able to compute a solution at param %d (time %g/%g)\n",i,t,traj.timeScaling.times.back());
      feasible = false;
      continue;
    }
    for(int j=0;j<solver.t.n;j++) {
      if(Abs(solver.t(j)) > robot.torqueMax(j)*(1+Epsilon)) {
	printf("Torque at param %d (time %g/%g) is infeasible\n",i,t,traj.timeScaling.times.back());
	printf("   |%g| > %g  at link %s\n",solver.t(j),robot.torqueMax(j),robot.LinkName(j).c_str());
	feasible = false;
      }
    }
  }
  return feasible;
}
    Array AmericanBasketPathPricer::state(const MultiPath& path,
                                          Size t) const {
        QL_REQUIRE(path.assetNumber() == assetNumber_, "invalid multipath");

        Array tmp(assetNumber_);
        for (Size i=0; i<assetNumber_; ++i) {
            tmp[i] = path[i][t]*scalingValue_;
        }

        return tmp;
    }
    /*
      Extract the relevant information from the whole path
     */
    LongstaffSchwartzMultiPathPricer::PathInfo 
    LongstaffSchwartzMultiPathPricer::transformPath(const MultiPath& multiPath)
    const {
        const Size numberOfAssets = multiPath.assetNumber();
        const Size numberOfTimes = timePositions_.size();

        Matrix path(numberOfAssets, numberOfTimes, Null<Real>());

        for (Size i = 0; i < numberOfTimes; ++i) {
            const Size pos = timePositions_[i];
            for (Size j = 0; j < numberOfAssets; ++j)
                path[j][i] = multiPath[j][pos];
        }
        
        PathInfo info(numberOfTimes);

        payoff_->value(path, forwardTermStructures_, info.payments, info.exercises, info.states);

        return info;
    }
예제 #10
0
파일: trajopt.cpp 프로젝트: bbgw/RobotSim
void ContactOptimizeTest2(const char* robfile,const char* config1,const char* config2)
{
  Robot robot;
  if(!robot.Load(robfile)) {
    printf("Unable to load robot file %s\n",robfile);
    return;
  }

  Vector a,b;
  ifstream ia(config1,ios::in);
  ifstream ib(config2,ios::in);
  ia >> a;
  ib >> b;
  if(!ia || !ib) {
    printf("Unable to load config file(s)\n");
    return;
  }
  ia.close();
  ib.close();

  printf("Automatically detecting contacts...\n");
  robot.UpdateConfig(a);
  ContactFormation formation;
  GetFlatContacts(robot,5e-3,formation);
  printf("Assuming friction 0.5\n");
  for(size_t i=0;i<formation.contacts.size();i++) {
    printf("%d contacts on link %d\n",formation.contacts[i].size(),formation.links[i]);
    for(size_t j=0;j<formation.contacts[i].size();j++)
      formation.contacts[i][j].kFriction = 0.5;
  }
  Stance stance;
  LocalContactsToStance(formation,robot,stance);

  MultiPath path;
  path.sections.resize(1);
  MultiPath::PathSection& section = path.sections[0];
  path.SetStance(stance,0);

  vector<IKGoal> ikGoals;
  path.GetIKProblem(ikGoals);
  RobotConstrainedInterpolator interp(robot,ikGoals);
  //Real xtol = 5e-2;
  Real xtol = 1e-1;
  interp.ftol = 1e-6;
  interp.xtol = xtol;
  if(!interp.Project(a)) {
    printf("Failed to project config a\n");
    return;
  }
  if(!interp.Project(b)) {
    printf("Failed to project config b\n");
    return;
  }
  cout<<"Start: "<<a<<endl;
  cout<<"Goal: "<<b<<endl;
  vector<Vector> milestones,milestones2;
  if(!interp.Make(a,b,milestones)) {
    printf("Failed to interpolate\n");
    return;
  }
  if(!interp.Make(b,a,milestones2)) {
    printf("Failed to interpolate\n");
    return;
  }
  milestones.insert(milestones.end(),++milestones2.begin(),milestones2.end());
  //milestones2 = milestones;
  //milestones.insert(milestones.end(),++milestones2.begin(),milestones2.end());
  {
    cout<<"Saving geometric path to temp.path"<<endl;
    ofstream out("temp.path",ios::out);
    for(size_t i=0;i<milestones.size();i++)
      out<<Real(i)/Real(milestones.size()-1)<<"   "<<milestones[i]<<endl;
    out.close();
  }
    
  section.milestones = milestones;

  vector<Real> divs(101);
  for(size_t i=0;i<divs.size();i++)
    divs[i] = Real(i)/(divs.size()-1);
  Timer timer;
  ContactTimeScaling scaling(robot);
  scaling.frictionRobustness = 0.25;
  scaling.torqueRobustness = 0.25;
  scaling.forceRobustness = 0.05;
  bool res=scaling.SetParams(path,divs);
  if(!res) {
    printf("Unable to set contact scaling, time %g\n",timer.ElapsedTime());
    printf("Saving to scaling_constraints.csv\n");
    ofstream outc("scaling_constraints.csv",ios::out);
    outc<<"collocation point,planeindex,normal x,normal y,offset"<<endl;
    for(size_t i=0;i<scaling.ds2ddsConstraintNormals.size();i++) 
      for(size_t j=0;j<scaling.ds2ddsConstraintNormals[i].size();j++) 
	outc<<i<<","<<j<<","<<scaling.ds2ddsConstraintNormals[i][j].x<<","<<scaling.ds2ddsConstraintNormals[i][j].y<<","<<scaling.ds2ddsConstraintOffsets[i][j]<<endl;
    return;
  }
  printf("Contact scaling init successful, time %g\n",timer.ElapsedTime());
  printf("Saving to scaling_constraints.csv\n");
  ofstream outc("scaling_constraints.csv",ios::out);
  outc<<"collocation point,planeindex,normal x,normal y,offset"<<endl;
  for(size_t i=0;i<scaling.ds2ddsConstraintNormals.size();i++) 
    for(size_t j=0;j<scaling.ds2ddsConstraintNormals[i].size();j++) 
      outc<<i<<","<<j<<","<<scaling.ds2ddsConstraintNormals[i][j].x<<","<<scaling.ds2ddsConstraintNormals[i][j].y<<","<<scaling.ds2ddsConstraintOffsets[i][j]<<endl;


  res=scaling.Optimize();
  if(!res) {
    printf("Time scaling failed in time %g.  Path may be dynamically infeasible.\n",timer.ElapsedTime());
    return;
  }
  printf("Time scaling solved in time %g, execution time %g\n",timer.ElapsedTime(),scaling.traj.timeScaling.times.back());
  scaling.Check(path);
  /*
  for(size_t i=0;i<scaling.traj.ds.size();i++) {
    printf("time %g: rate %g\n",scaling.traj.times[i],scaling.ds[i]);
  }
  */
  {
    cout<<"Saving dynamically optimized path to temp_opt.path"<<endl;
    ofstream out("temp_opt.path",ios::out);
    Real dt = scaling.traj.EndTime()/100;
    Real t=0;
    for(size_t i=0;i<=100;i++) {
      Vector x;
      scaling.traj.Eval(t,x);
      out<<t<<"\t"<<x<<endl;
      t += dt;
    }
    out.close();
  }
}
예제 #11
0
/************************************************************************

  Expands the single multi path into all possible sequence variants.
  Since this turns out to be the time-limiting process for long de nvoo,
  this is implemented using a quick branch and bound that works on
  edge variant indices. The SeqPaths are created only for the final
  set of sequences.

*************************************************************************/
void PrmGraph::fast_expand_multi_path_for_combo_scores(
									  AllScoreModels *model,
									  const MultiPath& multi_path, 
									  vector<SeqPath>& seq_paths,
									  score_t min_score,
									  score_t forbidden_pair_penalty,
									  int max_num_paths)
{
	const vector<AA_combo>& aa_edge_comobos = config->get_aa_edge_combos();
	vector<score_t> max_attainable_scores;

	const int num_edges = multi_path.edge_idxs.size();
	max_attainable_scores.resize(num_edges+1,0);
	
	int num_path_variants=1;
	int e;
	for (e=num_edges-1; e<num_edges; e++)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = multi_edges[e_idx];
		num_path_variants *= edge.variant_ptrs.size();
	}


	if (num_path_variants == 0)
	{
		cout << "Error: had an edge with 0 variants!" <<endl;
		exit(1);
	}

	// re-check the max attainable scores, this time compute all combo scores along the path
	// this will give a more accurate max attainable score, and also allow quick computation
	// of the expanded scores

	max_attainable_scores.clear();
	max_attainable_scores.resize(num_edges+1,0);
	vector<score_t> max_node_scores;
	max_node_scores.resize(num_edges+1,NEG_INF);

	for (e=0; e<=num_edges; e++)
	{
		const int n_edge_idx = (e>0 ? multi_path.edge_idxs[e-1] : -1);
		const int c_edge_idx = (e<num_edges ? multi_path.edge_idxs[e] : -1);
		const int node_idx = (n_edge_idx>=0 ? multi_edges[n_edge_idx].c_idx : multi_edges[c_edge_idx].n_idx);
		const int num_n_vars = (e>0 ? multi_edges[n_edge_idx].variant_ptrs.size() : 1);
		const int num_c_vars = (e<num_edges ? multi_edges[c_edge_idx].variant_ptrs.size() : 1);

		int j,k;
		for (j=0; j<num_n_vars; j++)
			for (k=0; k<num_c_vars; k++)
			{
				score_t combo_score = model->get_node_combo_score(this,node_idx,n_edge_idx,j,c_edge_idx,k);
				if (max_node_scores[e]<combo_score)
					max_node_scores[e]=combo_score;
			}
	}

	max_attainable_scores[num_edges]=max_node_scores[num_edges];
	for (e=num_edges-1; e>=0; e--)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = multi_edges[e_idx];

		max_attainable_scores[e]= max_attainable_scores[e+1] + 
			edge.max_variant_score + max_node_scores[e]; 
	}
	score_t max_path_score =  max_attainable_scores[0] - multi_path.num_forbidden_nodes * forbidden_pair_penalty;
	score_t min_delta_allowed = min_score - max_path_score;

	if (min_delta_allowed>0)
		return;

	// in this expansion method, all edges are stored (not only ones with more than one variant)
	// perform expansion using a heap and condensed path representation
	vector<int> var_positions;				   // holds the edge idxs
	vector<int> num_vars;
	vector<int> var_edge_positions;
	vector< vector< score_t > > var_scores;
	var_scores.clear();
	var_positions.clear();
	num_vars.clear();

	int num_aas_in_multipath = 0;
	for (e=0; e<num_edges; e++)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = multi_edges[e_idx];
		const int num_vars_in_edge = edge.variant_ptrs.size();
		vector<score_t> scores;

		num_aas_in_multipath+=edge.num_aa;

		int i;
		for (i=0; i<num_vars_in_edge; i++)
			scores.push_back(edge.variant_scores[i]);
		
		var_scores.push_back(scores);
		var_positions.push_back(e);
		num_vars.push_back(num_vars_in_edge);
		var_edge_positions.push_back(num_aas_in_multipath-edge.num_aa);
	}

	// create the SeqPaths from the edge_combos...
	const int num_positions = num_aas_in_multipath+1;
	SeqPath template_path;				// holds common elements to all paths
	template_path.n_term_aa = multi_path.n_term_aa;
	template_path.c_term_aa = multi_path.c_term_aa;
	template_path.n_term_mass = multi_path.n_term_mass;
	template_path.c_term_mass = multi_path.c_term_mass;
	template_path.charge = charge;
	template_path.multi_path_rank = multi_path.original_rank;
	template_path.path_score = 0;
	template_path.prm_ptr = (PrmGraph *)this;
	template_path.positions.clear();
	template_path.positions.resize(num_positions);

	template_path.num_forbidden_nodes = multi_path.num_forbidden_nodes;
	template_path.path_score -= template_path.num_forbidden_nodes * forbidden_pair_penalty;

	int pos_idx=0;
	for (e=0; e<multi_path.edge_idxs.size(); e++)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = get_multi_edge(e_idx);
		PathPos& pos = template_path.positions[pos_idx++];

		pos.breakage = edge.n_break;
		pos.edge_idx = e_idx;
		pos.mass =  edge.n_break->mass;
		pos.node_idx = edge.n_idx;
		
		int *variant_ptr = edge.variant_ptrs[0];
		const int num_aa = *variant_ptr++;
		int *aas = variant_ptr;

		if (edge.variant_ptrs.size() == 1)
		{
			pos.variant_ptr = edge.variant_ptrs[0];
			pos.edge_variant_score = edge.variant_scores[0];
			pos.aa = aas[0];
		}

		if (edge.num_aa == 1)
			continue;
		
		int j;
		for (j=1; j<edge.num_aa; j++)
		{
			PathPos& pos = template_path.positions[pos_idx++];
			pos.breakage = NULL;
			pos.aa = aas[j];
		}
	}

	if (pos_idx != num_aas_in_multipath)
	{
		cout << "Error: mismatches between positions and multipath length!" << endl;
		exit(1);
	}
	
	PathPos& last_pos = template_path.positions[num_positions-1];
	const int last_e_idx = multi_path.edge_idxs[e-1];
	const MultiEdge& last_edge = get_multi_edge(last_e_idx);
	last_pos.breakage = last_edge.c_break;
	last_pos.edge_idx =-1;
	last_pos.mass = last_edge.c_break->mass;
	last_pos.node_idx = last_edge.c_idx;
	

	const int num_multi_var_edges = var_positions.size();
	
	vector<var_combo>      combo_heap;
	vector<int> var_idxs;
	var_idxs.resize(num_multi_var_edges,0);
	const int last_var_pos = num_multi_var_edges-1;
	const int last_var_val = num_vars[last_var_pos];
	const score_t needed_var_score = min_score; // this is only the penalty for forbidden pairs
	while (1)
	{
		score_t idxs_score = 0;
		int k;
		for (k=0; k<var_idxs.size(); k++)
			idxs_score += var_scores[k][var_idxs[k]]; // this is the score for the edge variants (usually 0) 
		
		const vector<PathPos>& positions = template_path.positions;
		score_t path_score = idxs_score + template_path.path_score;
		
		// compute the node scores based on the edge variants
		// N-term node score
		vector<score_t> node_scores;
		node_scores.resize(var_idxs.size()+1,NEG_INF);

		node_scores[0] = model->get_node_combo_score(this,positions[0].node_idx,-1,0,
													positions[0].edge_idx,var_idxs[0]);
		path_score += node_scores[0];
		// middle nodes score
		int prev_edge_idx = positions[0].edge_idx;
		for (k=1; k<var_idxs.size(); k++)
		{
			const int p=var_edge_positions[k];
			const PathPos& pos = positions[p];
			node_scores[k] = model->get_node_combo_score(this,pos.node_idx,prev_edge_idx,var_idxs[k-1],
													pos.edge_idx,var_idxs[k]);
			path_score += node_scores[k];
			prev_edge_idx = pos.edge_idx;
		}

		// C-term node score
		node_scores[k] = model->get_node_combo_score(this,last_pos.node_idx,prev_edge_idx,var_idxs[k-1],-1,0);

		path_score += node_scores[k];
		
		if (path_score>=needed_var_score)
		{
			if (combo_heap.size()<max_num_paths)
			{
				var_combo v;
				v.path_score  = path_score;
				v.var_idxs    = var_idxs;
				v.node_scores = node_scores;
				combo_heap.push_back(v);
				if (combo_heap.size()== max_num_paths)
					make_heap(combo_heap.begin(),combo_heap.end());
			}
			else
			{
				const score_t score = path_score;
				if (score>combo_heap[0].path_score)
				{
					pop_heap(combo_heap.begin(),combo_heap.end());
					var_combo& combo  = combo_heap[max_num_paths-1];
					combo.path_score  = path_score;
					combo.var_idxs    = var_idxs;
					combo.node_scores = node_scores;
					push_heap(combo_heap.begin(),combo_heap.end());
				}
			}	
		}

		int j=0;
		while (j<num_multi_var_edges)
		{
			var_idxs[j]++;
			if (var_idxs[j]==num_vars[j])
			{
				var_idxs[j++]=0;
			}
			else
				break;
		}
		if (j==num_multi_var_edges)
			break;

	}


	seq_paths.clear();
	seq_paths.resize(combo_heap.size(),template_path);

	int i;
	for (i=0; i<combo_heap.size(); i++)
	{
		const var_combo& combo  = combo_heap[i];
		SeqPath& seq_path = seq_paths[i];

		// fill in info that changes with multi-variant edges
		int j;
		for (j=0; j<num_multi_var_edges; j++)
		{
			const int var_pos = var_positions[j];
			const int e_idx = multi_path.edge_idxs[var_pos];
			const MultiEdge& edge = get_multi_edge(e_idx);

			const int pos_idx = var_edge_positions[j];
		
			if (seq_path.positions[pos_idx].edge_idx !=  e_idx)
			{
				cout << "POS: " << pos_idx << endl;
				cout << "Error: mismatch in pos_idx and e_idx of a multipath!" << endl;
				cout << "looking for " << e_idx << endl;
				cout << "edge idxs:" << endl;
				int k;
				for (k=0; k<seq_path.positions.size(); k++)
					cout << k << "\t" << seq_path.positions[k].edge_idx << "\tnidx: " <<
					seq_path.positions[k].node_idx << endl;
				cout << endl;
				multi_path.print(config);

				this->print();

				exit(1);
			}

			PathPos& pos = seq_path.positions[pos_idx];
			const int variant_idx = combo.var_idxs[j];
			int *variant_ptr = edge.variant_ptrs[variant_idx];
			const int num_aa = *variant_ptr++;
			int *aas = variant_ptr;

			if (num_aa != edge.num_aa)
			{
				cout << "Error: edge and variant mixup!" << endl;
				exit(1);
			}

			pos.node_score = combo.node_scores[j];
			pos.edge_variant_score = edge.variant_scores[variant_idx];
			pos.variant_ptr = edge.variant_ptrs[variant_idx];
			pos.aa = aas[0];
	
			if (edge.num_aa == 1)
				continue;

			int k;
			for (k=1; k<edge.num_aa; k++)
			{
				PathPos& pos = seq_path.positions[pos_idx+k];
				pos.aa = aas[k];
			}
		}

		seq_path.positions[seq_path.positions.size()-1].node_score = combo.node_scores[num_multi_var_edges];
		seq_path.path_score=combo.path_score;
		float pen = seq_path.adjust_complete_sequence_penalty(this);

		seq_path.make_seq_str(config);
	}
}
예제 #12
0
bool ContactTimeScaling::SetParams(const MultiPath& path,const vector<Real>& paramDivs,int numFCEdges)
{
  Robot& robot = cspace.robot;
  CustomTimeScaling::SetPath(path,paramDivs);
  CustomTimeScaling::SetDefaultBounds();
  CustomTimeScaling::SetStartStop();

  ContactFormation formation;
  int oldSection = -1;
  LinearProgram_Sparse lp;
  NewtonEulerSolver ne(robot);
  //kinetic energy, coriolis force, gravity
  Vector3 gravity(0,0,-9.8);
  Vector C,G;
  //coefficients of time scaling
  Vector a,b,c;
  bool feasible=true;
  for(size_t i=0;i<paramDivs.size();i++) {
    Assert(paramSections[i] >= 0 && paramSections[i] < (int)path.sections.size());
    if(paramSections[i] != oldSection) {
      //reconstruct LP for the contacts in this section
      Stance stance;
      path.GetStance(stance,paramSections[i]);
      ToContactFormation(stance,formation);
      for(size_t j=0;j<formation.contacts.size();j++)
	for(size_t k=0;k<formation.contacts[j].size();k++) {
	  Assert(formation.contacts[j][k].kFriction > 0);
	  Assert(frictionRobustness < 1.0);
	  formation.contacts[j][k].kFriction *= (1.0-frictionRobustness);
	}

      //now formulate the LP.  Variable 0 is dds, variable 1 is ds^2
      //rows 1-n are torque max
      //rows n+1 - 2n are acceleration max
      //rows 2n+1 + 2n+numFCEdges*nc are the force constraints
      //vel max is encoded in the velocity variable
      int n = (int)robot.links.size();
      int nc = formation.numContactPoints();
#if TEST_NO_CONTACT
      nc = 0;
#endif // TEST_NO_CONTACT
      lp.Resize(n*2+numFCEdges*nc,2+3*nc);
      lp.A.setZero();
      lp.c.setZero();
      //fill out wrench matrix FC*f <= 0
#if !TEST_NO_CONTACT
      SparseMatrix FC;
      GetFrictionConePlanes(formation,numFCEdges,FC);
      lp.A.copySubMatrix(n*2,2,FC);
      for(int j=0;j<FC.m;j++)
	lp.p(n*2+j) = -forceRobustness;
#endif // !TEST_NO_CONTACT

      lp.l(0) = 0.0;
      lp.l(1) = -Inf;

      oldSection = paramSections[i];
    }
    //configuration specific 
    robot.UpdateConfig(xs[i]);
    robot.dq = dxs[i];
    ne.CalcResidualTorques(C);
    robot.GetGravityTorques(gravity,G);
    ne.MulKineticEnergyMatrix(dxs[i],a);
    ne.MulKineticEnergyMatrix(ddxs[i],b);
    b += C;
    c = G;

    //|a dds + b ds^2 + c - Jtf| <= torquemax*scale+shift
    for(int j=0;j<a.n;j++) {
      lp.A(j,0) = b(j);
      lp.A(j,1) = a(j);
      Real tmax = robot.torqueMax(j)*torqueLimitScale+torqueLimitShift;
      if(tmax < 0) tmax=0;
      lp.p(j) = tmax-c(j);
      lp.q(j) = -tmax-c(j);
    }
#if TEST_NO_CONTACT
    lp.p.set(Inf);
    lp.q.set(-Inf);
#else
    //fill out jacobian transposes
    int ccount=0;
    for(size_t l=0;l<formation.links.size();l++) {
      int link = formation.links[l];
      int target = (formation.targets.empty() ? -1 : formation.targets[l]);
      for(size_t j=0;j<formation.contacts[l].size();j++,ccount++) {
	Vector3 p=formation.contacts[l][j].x;
	//if it's a self-contact, then transform to world
	if(target >= 0)
	  p = robot.links[target].T_World*p;
	Vector3 v;
	int k=link;
	while(k!=-1) {
	  robot.links[k].GetPositionJacobian(robot.q[k],p,v);
	  if(v.x != 0.0) lp.A(k,2+ccount*3)=-v.x;
	  if(v.y != 0.0) lp.A(k,2+ccount*3+1)=-v.y;
	  if(v.z != 0.0) lp.A(k,2+ccount*3+2)=-v.z;
	  k=robot.parents[k];
	}
	k = target;
	while(k!=-1) {
	  robot.links[k].GetPositionJacobian(robot.q[k],p,v);
	  if(v.x != 0.0) lp.A(k,2+ccount*3)+=v.x;
	  if(v.y != 0.0) lp.A(k,2+ccount*3+1)+=v.y;
	  if(v.z != 0.0) lp.A(k,2+ccount*3+2)+=v.z;
	  k=robot.parents[k];
	}
      }
    }
    Assert(ccount == formation.numContactPoints());
#endif //TEST_NO_CONTACT

    //fill out acceleration constraint |ddx*ds^2 + dx*dds| <= amax
    for(int j=0;j<a.n;j++) {
      lp.q(a.n+j) = -robot.accMax(j);
      lp.p(a.n+j) = robot.accMax(j);
      lp.A(a.n+j,0) = ddxs[i][j];
      lp.A(a.n+j,1) = dxs[i][j];
    }

    //compute upper bounds from vel and acc max
    lp.u(0) = Inf; lp.u(1) = Inf;
    for(int j=0;j<a.n;j++) {
      if(dxs[i][j] < 0)
	lp.u(0) = Min(lp.u(0),Sqr(robot.velMin(j)/dxs[i][j]));
      else
	lp.u(0) = Min(lp.u(0),Sqr(robot.velMax(j)/dxs[i][j]));
    }

    //expand polytope
    Geometry::PolytopeProjection2D proj(lp);
    Geometry::UnboundedPolytope2D poly;
    proj.Solve(poly);
    if(poly.vertices.empty()) {
      //problem is infeasible?
      printf("Problem is infeasible at segment %d\n",i);
      cout<<"x = "<<xs[i]<<endl;
      cout<<"dx = "<<dxs[i]<<endl;
      cout<<"ddx = "<<ddxs[i]<<endl;
      lp.Print(cout);
      getchar();
      feasible=false;
    }
    /*
    if(i == 49) {
      cout<<"x = "<<xs[i]<<endl;
      cout<<"dx = "<<dxs[i]<<endl;
      cout<<"ddx = "<<ddxs[i]<<endl;
      lp.Print(cout);
      cout<<"Result: "<<endl;
      for(size_t j=0;j<poly.planes.size();j++) 
	cout<<poly.planes[j].normal.x<<" ds^2 + "<<poly.planes[j].normal.y<<" dds <= "<<poly.planes[j].offset<<endl;
      cout<<"Vertices: "<<endl;
      for(size_t j=0;j<poly.vertices.size();j++) {
	cout<<poly.vertices[j]<<endl;
      }
      getchar();
    }
    */
    ds2ddsConstraintNormals[i].resize(poly.planes.size());
    ds2ddsConstraintOffsets[i].resize(poly.planes.size());
    for(size_t j=0;j<poly.planes.size();j++) {
      ds2ddsConstraintNormals[i][j] = poly.planes[j].normal;
      ds2ddsConstraintOffsets[i][j] = poly.planes[j].offset;
      if(saveConstraintNames) {
        stringstream ss;
        ss<<"projected_constraint_plane_"<<j;
        ds2ddsConstraintNames[i].push_back(ss.str());
      }
    }
  }
  //done!
  return feasible;
}
예제 #13
0
/** @brief Completely interpolates, optimizes, and time-scales the
 * given MultiPath to satisfy its contact constraints.
 *
 * Arguments
 * - robot: the robot
 * - path: the MultiPath containing the milestones / stances of the motion
 * - interpTol: the tolerance that must be met for contact constraints for the
 *   interpolated path.
 * - numdivs: the number of grid points used for time-scaling
 * - traj (out): the output timed trajectory. (Warning, the spaces and manifolds in
 *   traj.path.segments will be bogus pointers.)
 * - torqueRobustness: a parameter in [0,1] determining the robustness margin 
 *   added to the torque constraint.  The robot's torques are scaled by a factor
 *   of (1-torqueRobustness).
 * - frictionRobustness: a parameter in [0,1] determinining the robustness margin
 *   added to the friction constraint.  The friction coefficients are scaled by
 *   a factor of (1-frictionRobustness).  Helps the path avoid slipping.
 * - forceRobustness: a minimum normal contact force that must be applied
 *   *at each contact point* (in Newtons).  Helps the trajectory avoid contact
 *   separation.
 * - savePath: if true, saves the interpolated MultiPath to disk.
 * - saveConstraints: if true, saves the time scaling convex program constraints
 *   to disk.
 * 
 * Return value is true if interpolation / time scaling was successful.
 * Failure indicates that the milestones could not be interpolated, or 
 * the path is not dynamically feasible.  For example, the milestones or
 * interpolated path might violate stability constraints.
 */
bool ContactOptimizeMultipath(Robot& robot,const MultiPath& path,
			      Real interpTol,int numdivs,
			      TimeScaledBezierCurve& traj,
			      Real torqueRobustness=0.0,
			      Real frictionRobustness=0.0,
			      Real forceRobustness=0.0,
			      bool savePath = true,
			      bool saveConstraints = false)
{
  Assert(torqueRobustness < 1.0);
  Assert(frictionRobustness < 1.0);

  Timer timer;
  MultiPath ipath;
  bool res=DiscretizeConstrainedMultiPath(robot,path,ipath,interpTol);
  if(!res) {
    printf("Could not discretize path, failing\n");
    return false;
  }

  int ns = 0;
  for(size_t i=0;i<ipath.sections.size();i++)
    ns += ipath.sections[i].milestones.size()-1;
  printf("Interpolated at resolution %g to %d segments, time %g\n",interpTol,ns,timer.ElapsedTime());
  if(savePath)
  {
    cout<<"Saving interpolated geometric path to temp.xml"<<endl;
    ipath.Save("temp.xml");
  }

  vector<Real> divs(numdivs);
  Real T = ipath.Duration();
  for(size_t i=0;i<divs.size();i++)
    divs[i] = T*Real(i)/(divs.size()-1);

  timer.Reset();
  ContactTimeScaling scaling(robot);
  //CustomTimeScaling scaling(robot);

  scaling.frictionRobustness = frictionRobustness;
  scaling.torqueLimitScale = 1.0-torqueRobustness;
  scaling.forceRobustness = forceRobustness;
  res=scaling.SetParams(ipath,divs);

  /*
  scaling.SetPath(ipath,divs);
  scaling.SetDefaultBounds();
  scaling.SetStartStop();
  bool res=true;
  */
  if(!res) {
    printf("Unable to set contact scaling, time %g\n",timer.ElapsedTime());
    if(saveConstraints) {
      printf("Saving to scaling_constraints.csv\n");
      ofstream outc("scaling_constraints.csv",ios::out);
      outc<<"collocation point,planeindex,normal x,normal y,offset"<<endl;
      for(size_t i=0;i<scaling.ds2ddsConstraintNormals.size();i++) 
	for(size_t j=0;j<scaling.ds2ddsConstraintNormals[i].size();j++) 
	  outc<<i<<","<<j<<","<<scaling.ds2ddsConstraintNormals[i][j].x<<","<<scaling.ds2ddsConstraintNormals[i][j].y<<","<<scaling.ds2ddsConstraintOffsets[i][j]<<endl;
    }
    return false;
  }
  printf("Contact scaling init successful, time %g\n",timer.ElapsedTime());
  if(saveConstraints) {
    printf("Saving to scaling_constraints.csv\n");
    ofstream outc("scaling_constraints.csv",ios::out);
    outc<<"collocation point,planeindex,normal x,normal y,offset"<<endl;
    for(size_t i=0;i<scaling.ds2ddsConstraintNormals.size();i++) 
      for(size_t j=0;j<scaling.ds2ddsConstraintNormals[i].size();j++) 
	outc<<i<<","<<j<<","<<scaling.ds2ddsConstraintNormals[i][j].x<<","<<scaling.ds2ddsConstraintNormals[i][j].y<<","<<scaling.ds2ddsConstraintOffsets[i][j]<<endl;
  }

  res=scaling.Optimize();
  if(!res) {
    printf("Time scaling failed in time %g.  Path may be dynamically infeasible.\n",timer.ElapsedTime());
    return false;
  }
  printf("Time scaling solved in time %g, execution time %g\n",timer.ElapsedTime(),scaling.traj.timeScaling.times.back());
  //scaling.Check(ipath);

  traj = scaling.traj;
  return true;
}
예제 #14
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);
  }
}
예제 #15
0
int main(int argc,const char** argv)
{
  if(argc <= 3) {
    printf("USAGE: ContactPlan [options] world_file configs stance\n");
    printf("OPTIONS:\n");
    printf("-o filename: the output linear path or multipath (default contactplan.xml)\n");
    printf("-p settings: set the planner configuration file\n");
    printf("-opt: do optimal planning (do not terminate on the first found solution)\n");
    printf("-n iters: set the default number of iterations per step (default 1000)\n");
    printf("-t time: set the planning time limit (default infinity)\n");
    printf("-m margin: set support polygon margin (default 0)\n");
    printf("-r robotindex: set the robot index (default 0)\n");
    return 0;
  }
  Srand(time(NULL));
  int robot = 0;
  const char* outputfile = "contactplan.xml";
  HaltingCondition termCond;
  string plannerSettings;
  int i;
  //parse command line arguments
  for(i=1;i<argc;i++) {
    if(argv[i][0]=='-') {
      if(0==strcmp(argv[i],"-n")) {
	termCond.maxIters = atoi(argv[i+1]);
	i++;
      }
      else if(0==strcmp(argv[i],"-t")) {
	termCond.timeLimit = atof(argv[i+1]);
	i++;
      }
      else if(0==strcmp(argv[i],"-opt")) {
	termCond.foundSolution = false;
      }
      else if(0==strcmp(argv[i],"-p")) {
	if(!GetFileContents(argv[i+1],plannerSettings)) {
	  printf("Unable to load planner settings file %s\n",argv[i+1]);
	  return 1;
	}
	i++;
      }
      else if(0==strcmp(argv[i],"-r")) {
	robot = atoi(argv[i+1]);
	i++;
      }
      else if(0==strcmp(argv[i],"-m")) {
	gSupportPolygonMargin = atof(argv[i+1]);
	i++;
      }
      else if(0==strcmp(argv[i],"-o")) {
	outputfile = argv[i+1];
	i++;
      }
      else {
	printf("Invalid option %s\n",argv[i]);
	return 1;
      }
    }
    else break;
  }
  if(i+3 < argc) {
    printf("USAGE: ContactPlan [options] world_file configs stance\n");
    return 1;
  }
  if(i+3 > argc) {
    printf("Warning: extra arguments provided\n");
  }
  const char* worldfile = argv[i];
  const char* configsfile = argv[i+1];
  const char* stancefile = argv[i+2];

  //Read in the world file
  XmlWorld xmlWorld;
  RobotWorld world;
  if(!xmlWorld.Load(worldfile)) {
    printf("Error loading world XML file %s\n",worldfile);
    return 1;
  }
  if(!xmlWorld.GetWorld(world)) {
    printf("Error loading world file %s\n",worldfile);
    return 1;
  }

  vector<Config> configs;
  {
    //Read in the configurations specified in configsfile
    ifstream in(configsfile);
    if(!in) {
      printf("Error opening configs file %s\n",configsfile);
      return false;
    }
    while(in) {
      Config temp;
      in >> temp;
      if(in) configs.push_back(temp);
    }
    if(configs.size() < 2) {
      printf("Configs file does not contain 2 or more configs\n");
      return 1;
    }
    in.close();
  }

  Stance stance;
  {
    //read in the stance specified by stancefile
    ifstream in(stancefile,ios::in);
    in >> stance;
    if(!in) {
      printf("Error loading stance file %s\n",stancefile);
      return 1;
    }
    in.close();
  }

  //If the stance has no contacts, use ContactPlan.  Otherwise, use StancePlan
  bool ignoreContactForces = false;
  if(NumContactPoints(stance)==0) {
    printf("No contact points in stance, planning without stability constraints\n");
    ignoreContactForces = true;
  }

  //set up the command line, store it into the MultiPath settings
  string cmdline;
  cmdline = argv[0];
  for(int i=1;i<argc;i++) {
    cmdline += " ";
    cmdline += argv[i];
  }
  MultiPath path;
  path.settings["robot"] = world.robots[robot].name;
  path.settings["command"] = cmdline;
  //begin planning
  bool feasible = true;
  Config qstart = world.robots[robot].robot->q;
  for(size_t i=0;i+1<configs.size();i++) {
    MilestonePath mpath;
    bool res = false;
    if(ignoreContactForces)
      res = ContactPlan(world,robot,configs[i],configs[i+1],stance,mpath,termCond,plannerSettings);
    else
      res = StancePlan(world,robot,configs[i],configs[i+1],stance,mpath,termCond,plannerSettings);
    if(!res) {
      printf("Planning from stance %d to %d failed\n",i,i+1);
      path.sections.resize(path.sections.size()+1);
      path.SetStance(stance,path.sections.size()-1);
      path.sections.back().milestones[0] = configs[i];
      path.sections.back().milestones[1] = configs[i+1];
      break;
    }
    else {
      path.sections.resize(path.sections.size()+1);
      path.sections.back().milestones.resize(mpath.NumMilestones());
      path.SetStance(stance,path.sections.size()-1);
      for(int j=0;j<mpath.NumMilestones();j++)
	path.sections.back().milestones[j] = mpath.GetMilestone(j);
      qstart = path.sections.back().milestones.back();
    }
  }
  if(feasible)
    printf("Path planning success! Saving to %s\n",outputfile);
  else
    printf("Path planning failure. Saving placeholder path to %s\n",outputfile);
  const char* ext = FileExtension(outputfile);
  if(ext && 0==strcmp(ext,"path")) {
    printf("Converted to linear path format\n");
    LinearPath lpath;
    Convert(path,lpath);
    ofstream f(outputfile,ios::out);
    lpath.Save(f);
    f.close();
  }
  else 
    path.Save(outputfile);
  return 0;
}
예제 #16
0
bool InterpolateConstrainedMultiPath(Robot& robot,const MultiPath& path,vector<GeneralizedCubicBezierSpline>& paths,Real xtol)
{
  //sanity check -- make sure it's a continuous path
  if(!path.IsContinuous()) {
    fprintf(stderr,"InterpolateConstrainedMultiPath: path is discontinuous\n");
    return false;
  }
  if(path.sections.empty()) {
    fprintf(stderr,"InterpolateConstrainedMultiPath: path is empty\n");
    return false;
  }

  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) {
      printf("Direct interpolating trajectory with res %g\n",res);
      //just interpolate directly
      RobotCSpace space(robot);
      RobotGeodesicManifold manifold(robot);
      paths.resize(path.sections.size());
      for(size_t i=0;i<path.sections.size();i++) {
	if(path.sections[i].times.empty()) {
	  SPLINE_INTERPOLATE_FUNC(path.sections[i].milestones,paths[i].segments,
			       &space,&manifold);
	  //uniform timing
	  paths[i].durations.resize(paths[i].segments.size());
	  Real dt=1.0/Real(paths[i].segments.size());
	  for(size_t j=0;j<paths[i].segments.size();j++)
	    paths[i].durations[j] = dt;
	}
	else {
	  SPLINE_INTERPOLATE_FUNC(path.sections[i].milestones,path.sections[i].times,paths[i].segments,
			       &space,&manifold);
	  //get timing from path
	  paths[i].durations.resize(paths[i].segments.size());
	  for(size_t j=0;j<paths[i].segments.size();j++)
	    paths[i].durations[j] = path.sections[i].times[j+1]-path.sections[i].times[j];
	}
      }
      return true;
    }
  }
  printf("Discretizing constrained trajectory at res %g\n",xtol);

  RobotCSpace cspace(robot);
  RobotGeodesicManifold manifold(robot);

  //create transition constraints and derivatives
  vector<vector<IKGoal> > stanceConstraints(path.sections.size());
  vector<vector<IKGoal> > transitionConstraints(path.sections.size()-1);
  vector<Config> transitionDerivs(path.sections.size()-1);
  for(size_t i=0;i<path.sections.size();i++) 
    path.GetIKProblem(stanceConstraints[i],i);
  for(size_t i=0;i+1<path.sections.size();i++) {
    //put all nonredundant constraints into transitionConstraints[i]
    transitionConstraints[i]=stanceConstraints[i];
    for(size_t j=0;j<stanceConstraints[i+1].size();j++) {
      bool res=AddGoalNonredundant(stanceConstraints[i+1][j],transitionConstraints[i]);
      if(!res) {
	fprintf(stderr,"Conflict between goal %d of stance %d and stance %d\n",j,i+1,i);
	fprintf(stderr,"  Link %d\n",stanceConstraints[i+1][j].link);
	return false;
      }
    }

    const Config& prev=path.sections[i].milestones[path.sections[i].milestones.size()-2];
    const Config& next=path.sections[i+1].milestones[1];
    manifold.InterpolateDeriv(prev,next,0.5,transitionDerivs[i]);
    transitionDerivs[i] *= 0.5;

    //check for overshoots a la MonotonicInterpolate
    Vector inslope,outslope;
    manifold.InterpolateDeriv(prev,path.sections[i].milestones.back(),1.0,inslope);
    manifold.InterpolateDeriv(path.sections[i].milestones.back(),next,0.0,outslope);
    for(int j=0;j<transitionDerivs[i].n;j++) {
      if(Sign(transitionDerivs[i][j]) != Sign(inslope[j]) || Sign(transitionDerivs[i][j]) != Sign(outslope[j])) transitionDerivs[i][j] = 0;
      else {
	if(transitionDerivs[i][j] > 0) {
	  if(transitionDerivs[i][j] > 3.0*outslope[j])
	    transitionDerivs[i][j] = 3.0*outslope[j];
	  if(transitionDerivs[i][j] > 3.0*inslope[j])
	    transitionDerivs[i][j] = 3.0*inslope[j];
	}
	else {
	  if(transitionDerivs[i][j] < 3.0*outslope[j])
	    transitionDerivs[i][j] = 3.0*outslope[j];
	  if(transitionDerivs[i][j] < 3.0*inslope[j])
	    transitionDerivs[i][j] = 3.0*inslope[j];
	}
      }
    }

    //project "natural" derivative onto transition manifold
    RobotIKFunction f(robot);
    f.UseIK(transitionConstraints[i]);
    GetDefaultIKDofs(robot,transitionConstraints[i],f.activeDofs);
    Vector temp(f.activeDofs.Size()),dtemp(f.activeDofs.Size()),dtemp2;
    f.activeDofs.InvMap(path.sections[i].milestones.back(),temp);
    f.activeDofs.InvMap(transitionDerivs[i],dtemp);
    Matrix J;
    f.PreEval(temp);
    f.Jacobian(temp,J);
    RobustSVD<Real> svd;
    if(!svd.set(J)) {
      fprintf(stderr,"Unable to set SVD of transition constraints %d\n",i);
      return false;
    }
    svd.nullspaceComponent(dtemp,dtemp2);
    dtemp -= dtemp2;
    f.activeDofs.Map(dtemp,transitionDerivs[i]);
  }

  //start constructing path
  paths.resize(path.sections.size());   
  for(size_t i=0;i<path.sections.size();i++) {
    paths[i].segments.resize(0);
    paths[i].durations.resize(0);

    Vector dxprev,dxnext;
    if(i>0) 
      dxprev.setRef(transitionDerivs[i-1]); 
    if(i<transitionDerivs.size()) 
      dxnext.setRef(transitionDerivs[i]); 
    if(stanceConstraints[i].empty()) {
      SPLINE_INTERPOLATE_FUNC(path.sections[i].milestones,paths[i].segments,&cspace,&manifold);
      DiscretizeSpline(paths[i],xtol);

      //Note: discretizeSpline will fill in the spline durations
    }
    else {
      RobotSmoothConstrainedInterpolator interp(robot,stanceConstraints[i]);
      interp.xtol = xtol;
      if(!MultiSmoothInterpolate(interp,path.sections[i].milestones,dxprev,dxnext,paths[i])) {
	/** TEMP - test no inter-section smoothing**/
	//if(!MultiSmoothInterpolate(interp,path.sections[i].milestones,paths[i])) {
	fprintf(stderr,"Unable to interpolate section %d\n",i);
	return false;
      }
    }
    //set the time scale if the input path is timed
    if(!path.sections[i].times.empty()) {
      //printf("Time scaling section %d to duration %g\n",i,path.sections[i].times.back()-path.sections[i].times.front());
      paths[i].TimeScale(path.sections[i].times.back()-path.sections[i].times.front());
    }
  }
  return true;
}
예제 #17
0
파일: trajopt.cpp 프로젝트: bbgw/RobotSim
void TimeOptimizeTestNLinkPlanar()
{
  const char* fn = "data/planar%d.rob";
  int ns [] = {5,10,15,20,25,30,40,50,60,70,80,90,100};
  Real tolscales [] = {3.95,3.55,2.73,2,2,2,1.8,1.6,1.42,1,1,1,1};
  int num = 13;
  char buf[256];
  for(int i=0;i<num;i++) {
    int n=ns[i];
    printf("Testing optimize %d\n",n);
    sprintf(buf,fn,n);
    Robot robot;
    if(!robot.Load(buf)) {
      fprintf(stderr,"Unable to load robot %s\n",buf);
      return;
    }
    int ee = robot.links.size()-1;
    Vector3 localpt(1,0,0);
    Real len = robot.links.size();
    //make a half circle
    Config a(robot.q.n,Pi/robot.links.size()),b;
    a[0] *= 0.5;
    robot.UpdateConfig(a);
    IKGoal goal,goaltemp;
    goal.link = ee;
    goal.localPosition = localpt;
    goal.SetFixedPosition(robot.links[ee].T_World*localpt);
    //cout<<"Goal position "<<goal.endPosition<<endl;
    goaltemp = goal;
    goaltemp.link = ee/2;
    goaltemp.SetFixedPosition(goal.endPosition*0.5);
    //cout<<"Middle goal position "<<goaltemp.endPosition<<endl;
    vector<IKGoal> onegoal(1),bothgoals(2);
    onegoal[0] = goal;
    bothgoals[0] = goal;
    bothgoals[1] = goaltemp;

    int iters=100;
    bool res=SolveIK(robot,bothgoals,1e-3,iters);
    if(!res) {
      fprintf(stderr,"Couldn't solve for target robot config\n");
      return;
    }
    b = robot.q;    
   
    Timer timer;
    GeneralizedCubicBezierSpline path;
    RobotSmoothConstrainedInterpolator interp(robot,onegoal);
    interp.xtol = 1e-3*tolscales[i];
    if(!interp.Make(a,b,path)) {
      fprintf(stderr,"Couldn't interpolate for target robot config\n");
      return;
    }
    printf("Solved for path with tol %g in time %g\n",interp.xtol,timer.ElapsedTime());

    {
      sprintf(buf,"trajopt_a_%d.config",n);
      ofstream out(buf);
      out<<a<<endl;
    }
    {
      sprintf(buf,"trajopt_b_%d.config",n);
      ofstream out(buf);
      out<<b<<endl;
    }
    {
      sprintf(buf,"trajopt_interp_%d.xml",n);
      vector<Real> times;
      vector<Config> configs;
      path.GetPiecewiseLinear(times,configs);
      MultiPath mpath;
      mpath.SetTimedMilestones(times,configs);
      mpath.SetIKProblem(onegoal);
      mpath.Save(buf);
    }
    {
      //unroll joints
      for(size_t i=0;i<path.segments.size();i++) {
	for(int j=0;j<path.segments[i].x0.n;j++) {
	  if(path.segments[i].x0[j] > Pi)
	    path.segments[i].x0[j] -= TwoPi;
	  if(path.segments[i].x1[j] > Pi)
	    path.segments[i].x1[j] -= TwoPi;
	  if(path.segments[i].x2[j] > Pi)
	    path.segments[i].x2[j] -= TwoPi;
	  if(path.segments[i].x3[j] > Pi)
	    path.segments[i].x3[j] -= TwoPi;
	}
      }
      sprintf(buf,"trajopt_interp_%d.spline",n);
      ofstream out(buf,ios::out);
      out.precision(10);
      path.Save(out);
    }

    TimeScaledBezierCurve curve;
    //curve.path = path;
    {
      sprintf(buf,"trajopt_interp_%d.spline",n);
      ifstream in(buf,ios::in);
      curve.path.Load(in);
      Assert(curve.path.segments.size() == path.durations.size());
      for(size_t i=0;i<curve.path.durations.size();i++) {
	Assert(FuzzyEquals(curve.path.durations[i],path.durations[i]));
	if(!curve.path.segments[i].x0.isEqual(path.segments[i].x0,Epsilon)) {
	  printf("Error on segment %d\n",i);
	  cout<<path.segments[i].x0<<endl;
	  cout<<curve.path.segments[i].x0<<endl;
	  cout<<"Distance: "<<path.segments[i].x0.distance(curve.path.segments[i].x0)<<endl;
	}
	Assert(curve.path.segments[i].x0.isEqual(path.segments[i].x0,Epsilon));
	Assert(curve.path.segments[i].x1.isEqual(path.segments[i].x1,Epsilon));
	Assert(curve.path.segments[i].x2.isEqual(path.segments[i].x2,Epsilon));
	Assert(curve.path.segments[i].x3.isEqual(path.segments[i].x3,Epsilon));
      }
    }
    Vector vmin(robot.q.n,-Pi),vmax(robot.q.n,Pi);
    Vector amin(robot.q.n,-Pi),amax(robot.q.n,Pi);
    timer.Reset();
    if(!curve.OptimizeTimeScaling(vmin,vmax,amin,amax)) {
      fprintf(stderr,"Optimize failed in time %g\n",timer.ElapsedTime());
      return;
    }
    printf("Solved time optimization with %d segments in time %g\n",curve.path.segments.size(),timer.ElapsedTime());
    
    //output optimized path
    {
      Real dt = 0.5;
      vector<Real> times;
      vector<Config> configs;
      /*curve.GetDiscretizedPath(dt,configs);
      times.resize(configs.size());
      for(size_t j=0;j<times.size();j++)
	times[j] = j*dt;
      */
      curve.GetPiecewiseLinear(times,configs);
      MultiPath mpath;
      mpath.SetIKProblem(onegoal);
      mpath.SetTimedMilestones(times,configs);
      sprintf(buf,"trajopt_opt_%d.xml",n);
      mpath.Save(buf);
    }
  }
}
예제 #18
0
파일: trajopt.cpp 프로젝트: bbgw/RobotSim
void ContactOptimizeTest()
{
  Robot robot;
  if(!robot.Load("data/simple_2d_biped.rob")) {
    printf("Unable to load data/simple_2d_biped.rob\n");
    return;
  }

  MultiPath path;
  path.sections.resize(1);
  MultiPath::PathSection& section = path.sections[0];
  section.holds.resize(2);
  section.holds[0].contacts.resize(2);
  section.holds[0].contacts[0].x.set(-0.4,-0.1,0);
  section.holds[0].contacts[1].x.set(-0.4,0.1,0);
  section.holds[0].contacts[0].n.set(0,0,1);
  section.holds[0].contacts[1].n.set(0,0,1);
  section.holds[0].contacts[0].kFriction = 0.5;
  section.holds[0].contacts[1].kFriction = 0.5;
  section.holds[1].contacts.resize(2);
  section.holds[1].contacts[0].x.set(0.4,-0.1,0);
  section.holds[1].contacts[1].x.set(0.4,0.1,0);
  section.holds[1].contacts[0].n.set(0,0,1);
  section.holds[1].contacts[1].n.set(0,0,1);
  section.holds[1].contacts[0].kFriction = 0.5;
  section.holds[1].contacts[1].kFriction = 0.5;
  section.holds[0].link = 7;
  section.holds[1].link = 9;
  section.holds[0].SetupIKConstraint(Vector3(0.5,-0.1,0),Vector3(Zero));
  section.holds[1].SetupIKConstraint(Vector3(0.5,-0.1,0),Vector3(Zero));
  vector<IKGoal> ikGoals;
  path.GetIKProblem(ikGoals);

  RobotConstrainedInterpolator interp(robot,ikGoals);
  Real xtol = 5e-2;
  interp.ftol = 1e-4;
  interp.xtol = xtol;
  Vector a(7),b(7);
  ifstream ia("simple_2d_biped/a.config",ios::in);
  ifstream ib("simple_2d_biped/b.config",ios::in);
  ia >> a;
  ib >> b;
  ia.close();
  ib.close();
  if(!interp.Project(a)) {
    printf("Failed to project config a\n");
    return;
  }
  if(!interp.Project(b)) {
    printf("Failed to project config b\n");
    return;
  }
  cout<<"Start: "<<a<<endl;
  cout<<"Goal: "<<b<<endl;
  vector<Vector> milestones,milestones2;
  if(!interp.Make(a,b,milestones)) {
    printf("Failed to interpolate\n");
    return;
  }
  if(!interp.Make(b,a,milestones2)) {
    printf("Failed to interpolate\n");
    return;
  }
  milestones.insert(milestones.end(),++milestones2.begin(),milestones2.end());
  //milestones2 = milestones;
  //milestones.insert(milestones.end(),++milestones2.begin(),milestones2.end());
  {
    cout<<"Saving geometric path to temp.path"<<endl;
    ofstream out("temp.path",ios::out);
    for(size_t i=0;i<milestones.size();i++)
      out<<Real(i)/Real(milestones.size()-1)<<"   "<<milestones[i]<<endl;
    out.close();
  }
    
  section.milestones = milestones;

  vector<Real> divs(401);
  for(size_t i=0;i<divs.size();i++)
    divs[i] = Real(i)/(divs.size()-1);
  Timer timer;
  ContactTimeScaling scaling(robot);
  scaling.frictionRobustness = 0.25;
  scaling.torqueRobustness = 0.25;
  scaling.forceRobustness = 0.1;
  bool res=scaling.SetParams(path,divs);
  if(!res) {
    printf("Unable to set contact scaling, time %g\n",timer.ElapsedTime());
    return;
  }
  printf("Contact scaling init successful, time %g\n",timer.ElapsedTime());
  ofstream outc("scaling_constraints.csv",ios::out);
  outc<<"collocation point,planeindex,normal x,normal y,offset"<<endl;
  for(size_t i=0;i<scaling.ds2ddsConstraintNormals.size();i++) 
    for(size_t j=0;j<scaling.ds2ddsConstraintNormals[i].size();j++) 
      outc<<i<<","<<j<<","<<scaling.ds2ddsConstraintNormals[i][j].x<<","<<scaling.ds2ddsConstraintNormals[i][j].y<<","<<scaling.ds2ddsConstraintOffsets[i][j]<<endl;
  res = scaling.Optimize();
  if(!res) {
    printf("Time scaling failed in time %g.  Path may be dynamically infeasible.\n",timer.ElapsedTime());
    return;
  }
  printf("Time scaling solved in time %g, execution time %g\n",timer.ElapsedTime(),scaling.traj.timeScaling.times.back());

  printf("\n");
  printf("Checking path for feasibility...\n");
  scaling.Check(path);
  /*
  for(size_t i=0;i<scaling.traj.ds.size();i++) {
    printf("time %g: rate %g\n",scaling.traj.times[i],scaling.ds[i]);
  }
  */
  {
    cout<<"Saving dynamically optimized path to temp_opt.path"<<endl;
    ofstream out("temp_opt.path",ios::out);
    int numdivs = 200;
    Real dt = scaling.traj.EndTime()/numdivs;
    Real t=0;
    for(size_t i=0;i<=numdivs;i++) {
      Vector x;
      scaling.traj.Eval(t,x);
      out<<t<<"\t"<<x<<endl;
      t += dt;
    }
    out.close();
  }
}
예제 #19
0
/************************************************************************

  Expands the single multi path into all possible sequence variants.
  Since this turns out to be the time-limiting process for long de nvoo,
  this is implemented using a quick branch and bound that works on
  edge variant indices. The SeqPaths are created only for the final
  set of sequences.

*************************************************************************/
void PrmGraph::fast_expand_multi_path(const MultiPath& multi_path, 
									  vector<SeqPath>& seq_paths,
									  score_t min_score,
									  score_t forbidden_pair_penalty,
									  int max_num_paths) const
{
	const vector<AA_combo>& aa_edge_comobos = config->get_aa_edge_combos();
	vector<score_t> max_attainable_scores;

	const int num_edges = multi_path.edge_idxs.size();
	max_attainable_scores.resize(num_edges+1,0);
	
	int num_path_variants=1;
	int e;
	for (e=num_edges-1; e>=0; e--)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = multi_edges[e_idx];

		max_attainable_scores[e]= max_attainable_scores[e+1] + 
			edge.max_variant_score + edge.c_break->score; 
		num_path_variants *= edge.variant_ptrs.size();
	}

	const score_t max_path_score =  multi_edges[multi_path.edge_idxs[0]].n_break->score + 
									max_attainable_scores[0];
	const score_t min_delta_allowed = min_score - max_path_score;

	if (min_delta_allowed>0)
		return; // this multipath won't help much

	if (num_path_variants == 0)
	{
		cout << "Error: had an edge with 0 variants!" <<endl;
		exit(1);
	}

	// perform expansion using a heap and condensed path representation
	vector<int> var_positions;				   // holds the edge idxs
	vector<int> num_vars;
	vector<int> var_edge_positions;
	vector< vector< score_t > > var_scores;
	var_scores.clear();
	var_positions.clear();
	num_vars.clear();
	int num_aas_in_multipath = 0;
	for (e=0; e<num_edges; e++)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = multi_edges[e_idx];
		const int num_vars_in_edge = edge.variant_ptrs.size();
		vector<score_t> scores;

		num_aas_in_multipath+=edge.num_aa;

		if (num_vars_in_edge>1)
		{
			int i;
			for (i=0; i<num_vars_in_edge; i++)
				scores.push_back(edge.variant_scores[i]);
		
			var_scores.push_back(scores);
			var_positions.push_back(e);
			num_vars.push_back(num_vars_in_edge);
			var_edge_positions.push_back(num_aas_in_multipath-edge.num_aa);

		//	cout << e << "\t" << e_idx << "\t" << num_vars_in_edge << "\t" << edge.num_aa << endl;
		}	
	}

		// create the SeqPaths from the edge_combos...
	const int num_positions = num_aas_in_multipath+1;
	SeqPath template_path;				// holds common elements to all paths
	template_path.n_term_aa = multi_path.n_term_aa;
	template_path.c_term_aa = multi_path.c_term_aa;
	template_path.n_term_mass = multi_path.n_term_mass;
	template_path.c_term_mass = multi_path.c_term_mass;
	template_path.multi_path_rank = multi_path.original_rank;
	template_path.path_score = 0;
	template_path.prm_ptr = (PrmGraph *)this;
	template_path.positions.clear();
	template_path.positions.resize(num_positions);

	template_path.num_forbidden_nodes = multi_path.num_forbidden_nodes;
	template_path.path_score -= template_path.num_forbidden_nodes * forbidden_pair_penalty;

	int pos_idx=0;
	for (e=0; e<multi_path.edge_idxs.size(); e++)
	{
		const int e_idx = multi_path.edge_idxs[e];
		const MultiEdge& edge = get_multi_edge(e_idx);
		PathPos& pos = template_path.positions[pos_idx++];

		pos.breakage = edge.n_break;
		pos.edge_idx = e_idx;
		pos.mass =  edge.n_break->mass;
		pos.node_score = edge.n_break->score;
		pos.node_idx = edge.n_idx;
		template_path.path_score += pos.node_score;

		int *variant_ptr = edge.variant_ptrs[0];
		const int num_aa = *variant_ptr++;
		int *aas = variant_ptr;

		if (edge.variant_ptrs.size() == 1)
		{
			pos.edge_variant_score = edge.variant_scores[0];
			pos.aa = aas[0];
			template_path.path_score += pos.edge_variant_score;
		}

		if (edge.num_aa == 1)
			continue;
		
		int j;
		for (j=1; j<edge.num_aa; j++)
		{
			PathPos& pos = template_path.positions[pos_idx++];
			pos.breakage = NULL;
			pos.aa = aas[j];
		}
	}

	if (pos_idx != num_aas_in_multipath)
	{
		cout << "Error: mismatches between positions and multipath length!" << endl;
		exit(1);
	}
	
	PathPos& last_pos = template_path.positions[num_positions-1];
	const int last_e_idx = multi_path.edge_idxs[e-1];
	const MultiEdge& last_edge = get_multi_edge(last_e_idx);
	last_pos.breakage = last_edge.c_break;
	last_pos.edge_idx =-1;
	last_pos.mass = last_edge.c_break->mass;
	last_pos.node_idx = last_edge.c_idx;
	last_pos.node_score = last_edge.c_break->score;

	template_path.path_score += last_pos.node_score;

	const int num_multi_var_edges = var_positions.size();
	if (num_multi_var_edges == 0)
	{
		seq_paths.resize(1);
		seq_paths[0]=template_path;
		return;
	}

	vector<var_combo>      combo_heap;
	vector<int> idxs;
	idxs.resize(num_multi_var_edges,0);
	const int last_var_pos = num_multi_var_edges-1;
	const int last_var_val = num_vars[last_var_pos];
	const score_t needed_var_score = min_score - template_path.path_score;
	while (1)
	{
		score_t idxs_score = 0;
		int k;
		for (k=0; k<idxs.size(); k++)
			idxs_score += var_scores[k][idxs[k]];
		
		if (idxs_score>=needed_var_score)
		{
			if (combo_heap.size()<max_num_paths)
			{
				var_combo v;
				v.path_score = template_path.path_score + idxs_score;
				v.var_idxs = idxs;
				combo_heap.push_back(v);
				if (combo_heap.size()== max_num_paths)
					make_heap(combo_heap.begin(),combo_heap.end());
			}
			else
			{
				const score_t score = template_path.path_score + idxs_score;
				if (score>combo_heap[0].path_score)
				{
					pop_heap(combo_heap.begin(),combo_heap.end());
					combo_heap[max_num_paths-1].path_score = score;
					combo_heap[max_num_paths-1].var_idxs = idxs;
					push_heap(combo_heap.begin(),combo_heap.end());
				}
			}	
		}

		int j=0;
		while (j<num_multi_var_edges)
		{
			idxs[j]++;
			if (idxs[j]==num_vars[j])
			{
				idxs[j++]=0;
			}
			else
				break;
		}
		if (j==num_multi_var_edges)
			break;

	}

	seq_paths.clear();
	seq_paths.resize(combo_heap.size(),template_path);

	int i;
	for (i=0; i<combo_heap.size(); i++)
	{
		const var_combo& combo  = combo_heap[i];
		SeqPath& seq_path = seq_paths[i];

		// fill in info that changes with multi-variant edges
		int j;
		for (j=0; j<num_multi_var_edges; j++)
		{
			const int var_pos = var_positions[j];
			const int e_idx = multi_path.edge_idxs[var_pos];
			const MultiEdge& edge = get_multi_edge(e_idx);

			const int pos_idx = var_edge_positions[j];
		
			if (seq_path.positions[pos_idx].edge_idx !=  e_idx)
			{
				cout << "POS: " << pos_idx << endl;
				cout << "Error: mismatch in pos_idx and e_idx of a multipath!" << endl;
				cout << "looking for " << e_idx << endl;
				cout << "edge idxs:" << endl;
				int k;
				for (k=0; k<seq_path.positions.size(); k++)
					cout << k << "\t" << seq_path.positions[k].edge_idx << "\tnidx: " <<
					seq_path.positions[k].node_idx << endl;
				cout << endl;
				multi_path.print(config);

				this->print();

				exit(1);
			}

			PathPos& pos = seq_path.positions[pos_idx];
			const int variant_idx = combo.var_idxs[j];
			int *variant_ptr = edge.variant_ptrs[variant_idx];
			const int num_aa = *variant_ptr++;
			int *aas = variant_ptr;

			if (num_aa != edge.num_aa)
			{
				cout << "Error: edge and variant mixup!" << endl;
				exit(1);
			}

			pos.edge_variant_score = edge.variant_scores[variant_idx];
			pos.aa = aas[0];
		//	pos.edge_var_idx = variant_idx;

			if (edge.num_aa == 1)
				continue;

			int k;
			for (k=1; k<edge.num_aa; k++)
			{
				PathPos& pos = seq_path.positions[pos_idx+k];
				pos.aa = aas[k];
			}
		}

		//seq_path.path_score = max_path_score + combo.path_delta;
		seq_path.path_score=combo.path_score;
		seq_path.make_seq_str(config);
	}
}