コード例 #1
0
Milestone* Milestone::makeRandomMilestone(Map& map) {
  for (int i = 0; i < MAX_BRANCH_CREATION_ATTEMPS; ++i) {
    // TODO: normal distribution?
    float speed = randFloat(-0.05, 0.3);
    // float speed = randFloat(0.1, 0.3);
    // float speed = randFloat(-0.2, 0.2);
    float turnRateRange = 1 - fabs(speed*2);
    float turnRate = randFloat(-turnRateRange, turnRateRange);
    int numCycles = (rand() % 70) + 30;

    Pose endPose = getEndPose();
    bool failed = false;
    for (int cycle = 0; cycle < numCycles; ++cycle) {
      endPose = propogateDynamics(endPose, speed, turnRate);
      if (map.robotAreaOccupied(endPose)) {
        // this motion path wasn't possible
        failed = true;
        break;
      }
    }
    if (!failed) {
      return new Milestone(this, endPose, speed, turnRate, numCycles);
    }
    // try another set of values
  }
  return NULL;
}
コード例 #2
0
ファイル: umanarc.cpp プロジェクト: savnik/LaserNavigation
UPoseV UManArc::getEndPoseV(UPoseV startPoseV)
{
  UPoseV result;
  //
  result = startPoseV + getEndPose();
  result.setVel(vel);
  return result;
}
コード例 #3
0
ファイル: smooth_path.cpp プロジェクト: Aharobot/bk_nav
// Combines all consecutive turn-in-place segments
p_nav::Path replaceMultipleTurns(const p_nav::Path& path)
{
	p_nav::PathSegment currseg, nextseg, newseg;
	int end_idx;
	geometry_msgs::PoseStamped start, end;
	p_nav::Path newpath;
	newpath.header = path.header;
	
	for(unsigned int path_idx = 0; path_idx < path.segs.size(); path_idx++)
	{
		currseg = path.segs.at(path_idx);
		
		// If the current seg is a turn in place
		if(currseg.seg_type == p_nav::PathSegment::SPIN_IN_PLACE)
		{
			end_idx = path_idx;
			
			// Look forward and find the last consecutive turn-in-place segs
			while( end_idx+1 < path.segs.size() // the next seg is in range and the next seg is a spin
			    && path.segs.at(end_idx+1).seg_type == p_nav::PathSegment::SPIN_IN_PLACE)
			{
				end_idx++;
				//ROS_INFO("Combining seg %d with %d", path_idx, end_idx);
			}
			
			start = getStartPose(currseg);
			end   = getEndPose  (path.segs.at(end_idx));

			// Combine all into a single segment
			newseg = makePathSegment(
			           start.pose.position.x, start.pose.position.y, tf::getYaw(start.pose.orientation),
					       end.pose.position.x  , end.pose.position.y  , tf::getYaw(end.pose.orientation));
			newseg.header     = currseg.header;
			newseg.seg_number = currseg.seg_number;
			newpath.segs.push_back(newseg);
			
			// We've now taken care of all segments including end_idx
			path_idx = end_idx;
			if( path_idx >= path.segs.size() )
				break;
		}// if turn in place
		else{
			newpath.segs.push_back(currseg);
		}
	}//for
	return newpath;
}
コード例 #4
0
ファイル: smooth_path.cpp プロジェクト: Aharobot/bk_nav
// Resamples the path's segments
p_nav::Path
smoothPath(const p_nav::Path& path)
{
	// Smoothing is possible with more than 2 segments
	if( path.segs.size() < 2 ) {
		return path;
	}
	
	p_nav::Path         smoothpath;
	p_nav::PathSegment  newseg, currseg, nextseg, prevseg;
	geometry_msgs::Pose start, start2, end, end2;

	// Preserve the path's header information
	smoothpath.header = path.header;
	smoothpath.segs.clear();
	
	for( unsigned int i=0; i<path.segs.size() - 1; i++ )
	{
		currseg = path.segs.at(i);
		
		// Skip over turn-in-place segments
		if( currseg.seg_type != p_nav::PathSegment::ARC ) {
			smoothpath.segs.push_back(currseg);
			continue;
		}
		
		// First segment in the path:
		if( i==0 )
		{
			nextseg = path.segs.at(i+1);
			
			start   = getStartPose(currseg).pose;
			end     = getEndPose  (currseg).pose;
			end2    = getStartPose(nextseg).pose;
			
			end.orientation = averageAngles(end.orientation, end2.orientation);
		}
		// Last segment in the path:
		else if( i == path.segs.size()-1 )
		{
			prevseg = path.segs.at(i-1);
		
			start   = getEndPose  (prevseg).pose;
			start2  = getStartPose(currseg).pose;
			end     = getEndPose  (currseg).pose;
			
			start.orientation = averageAngles(start.orientation, start2.orientation);
		}
		// Middle segment:
		else
		{
			prevseg = path.segs.at(i-1);
			nextseg = path.segs.at(i+1);
			
			start   = getEndPose  (prevseg).pose;
			start2  = getStartPose(currseg).pose;
			end     = getEndPose  (currseg).pose;
			end2    = getStartPose(nextseg).pose;
			
			start.orientation = averageAngles(start.orientation, start2.orientation);
			end.orientation   = averageAngles(end  .orientation, end2  .orientation);
		}

		// Create a new segment
		newseg = makePathSegment(start.position.x, start.position.y, tf::getYaw(start.orientation),
				                     end  .position.x, end  .position.y, tf::getYaw(end  .orientation));

		// Preserve some information from the current segment
		newseg.header     = currseg.header;
		newseg.seg_number = currseg.seg_number;
		
		// Make sure the smoothing didn't mess anything up too badly
		double start_ang_diff = tf::getYaw(subtractAngles(getStartPose(currseg).pose.orientation, getStartPose(newseg).pose.orientation));
		double end_ang_diff = tf::getYaw(subtractAngles(getEndPose(currseg).pose.orientation, getEndPose(newseg).pose.orientation));
		double angle_threshold = 3.141/16;
		
		double length_difference = (newseg.seg_length - currseg.seg_length)/currseg.seg_length;
		double length_threshold = .10;
		
		if( fabs(length_difference) > length_threshold
		 || fabs(start_ang_diff   ) > angle_threshold
		 || fabs(end_ang_diff     ) > angle_threshold )
		{
			ROS_WARN("Smoothing produced weird results at segment %lu/%lu", i+1, path.segs.size());
			ROS_WARN("length_difference=%.2f, angle diffs %.2fpi, %.2fpi", length_difference, start_ang_diff/3.141, end_ang_diff/3.141);
			smoothpath.segs.push_back(currseg);
		}
		else {		
			smoothpath.segs.push_back(newseg);
		}
	}
	return smoothpath;
}
コード例 #5
0
ファイル: umanarc.cpp プロジェクト: savnik/LaserNavigation
double UManArc::getDistanceXYSigned(UPosition pos, int * where,
                                    bool posIsRight,
                                    bool centerOnly,
                                    UPose * pHit,
                                    double * atT)
{
  double cy; // center
  double rx, ry;
  double d, dist = 0.0;
  double ang, aa, ea;
  int w = 3;
  const double halfPi = M_PI / 2.0;
  const double twoPi = M_PI * 2.0;
  //
  // find arc center
  if (angle > 0)
    cy = radius;
  else
    cy = -radius;
  ang = atan2(pos.y - cy, pos.x);
  // convert to angle relative to arc
  if (angle < 0)
    ang = halfPi - ang;
  else
    ang = halfPi + ang;
  // make all angles positive
  if (ang < 0.0)
    ang += twoPi;
  aa = absd(angle);
  // distance from turn center
  d = sqrt(sqr(pos.x) + sqr(pos.y - cy));
  // test for within arc - outside or inside
  if ((ang >= 0) and (ang <= aa))
  { // positive is to the right
    dist = (d - radius) * signofd(angle);
    w = 0;
    if (pHit != NULL)
    { // calculate hit position too.
      pHit->x = radius * sin(ang);
      if (angle < 0.0)
        pHit->y = cy + radius * cos(ang);
      else
        pHit->y = cy - radius * cos(ang);
      pHit->h = ang;
    }
    if (atT != NULL)
      // return distance into manoeuvre
      *atT = ang * radius;
  }
  else if (not centerOnly)
  { // closer to one of ends
    if ((ang - twoPi) < (aa - ang))
    { // high end is closer
      rx = radius * sin(aa);
      if (angle < 0.0)
        ry = cy + radius * cos(aa);
      else
        ry = cy - radius * cos(aa);
      dist = sqrt(sqr(pos.x - rx) + sqr(pos.y - ry));
      w = 2;
      if (pHit != NULL)
        *pHit = getEndPose();
      // get side of exit direction
      // get angle from exit position to position
      ea = atan2(pos.y - ry, pos.x - rx);
      if (ea > angle)
        // position is to the left of exit direction
        dist = -dist;
    }
    else
    { // distance from (0.0, 0.0)
      dist = sqrt(sqr(pos.x) + sqr(pos.y));
      w = 1;
      if (pHit != NULL)
        // hitpoint is 0,0
        pHit->set(0.0, 0.0, 0.0);
      if (pos.y > 0.0)
        // to the left of entry direction - is negative
        dist = -dist;
    }
  }
  if (where != NULL)
    *where = w;
  if (not posIsRight)
    dist = -dist;
  return dist;
}