void Costmap2D::updateWorld(double robot_x, double robot_y, 
      const vector<Observation>& observations, const vector<Observation>& clearing_observations){
    //reset the markers for inflation
    memset(markers_, 0, size_x_ * size_y_ * sizeof(unsigned char));

    //make sure the inflation queue is empty at the beginning of the cycle (should always be true)
    ROS_ASSERT_MSG(inflation_queue_.empty(), "The inflation queue must be empty at the beginning of inflation");

    //raytrace freespace
    raytraceFreespace(clearing_observations);

    //if we raytrace X meters out... we must re-inflate obstacles within the containing square of that circle
    double inflation_window_size = 2 * (max_raytrace_range_ + inflation_radius_);

    //clear all non-lethal obstacles in preparation for re-inflation
    clearNonLethal(robot_x, robot_y, inflation_window_size, inflation_window_size);

    //reset the inflation window
    resetInflationWindow(robot_x, robot_y, inflation_window_size + 2 * inflation_radius_, inflation_window_size + 2 * inflation_radius_, inflation_queue_, false);

    //now we also want to add the new obstacles we've received to the cost map
    updateObstacles(observations, inflation_queue_);

    inflateObstacles(inflation_queue_);
  }
Пример #2
0
void
SSLPathPlanner::globalStateRcvd (const ssl_msgs::GlobalState::ConstPtr &global_msg)
{
  if (!global_st_rcvd)
    global_st_rcvd = true;
  global_state = *global_msg;

  if (team_ == ssl::BLUE)
  {
    for (uint8_t i = 0; i < ssl::config::TEAM_CAPACITY; i++)
      team_state_[i] = global_state.blue_team[i];
  }
  else
  {
    for (uint8_t i = 0; i < ssl::config::TEAM_CAPACITY; i++)
      team_state_[i] = global_state.yellow_team[i];
  }

  updateObstacles ();
}
Пример #3
0
void VO2Controller::update(float dt)
{
	updatePath(dt);
	updateObstacles(0);

	float maxVelocity = mover->getMaxVelocity(0);
	// Определяем, как далеко осталось до ближайшего вейпоинта и 
	// выбираем соответствующую стратегию движения
	//Pose::vec targetDir = this->pathDirection();
	//float distance=targetDir.length();
	//const float targetCloseFactor = 0.2f;
	//vec2f size = mover->getUnit()->getOOBB().size();
	//float sphereSize=1.3 * mover->getUnit()->getBoundingSphere().radius;
	float turningSpeed = mover->getMaxVelocity(1);
	float turningRadius = maxVelocity / turningSpeed;
	Pose moverPose = mover->getGlobalPose();
	Pose::vec velocity = Pose::vec::zero();
	Pose::vec preferedDirection = Pose::vec::zero();
	
	float preferedAngle = 0;
	float preferedSpeed = 0;
	bool findMax = true;
	bool turnOnly = false;
	if( pathCurrent != -1 )
	{
		Pose::vec pathDir = pathDirection();
		Pose::vec targ = targetScale * pathDir;
		Pose::vec path = pathErrorScale * pathError();

		if( fabs( pathDir[0] ) < 2 * turningRadius && fabs( pathDir[1] ) < 2*turningRadius)
		{
			float x = pathDir & moverPose.axisX();
			float y = fabs(pathDir & moverPose.axisY()) - turningRadius;
			turnOnly = ( x*x  + y*y < turningRadius*turningRadius );
		}

		preferedDirection = normalise(path + targ);
		preferedAngle = atan2(preferedDirection[1], preferedDirection[0]);	// а не пойти ли нам вон туда
		preferedSpeed = maxVelocity;										// и побыстрее
		MoverVehicle * mv = (MoverVehicle*)mover;
		if(mv->definition->kinematic)
		{
			Pose::vec bodyVelocityLinear = conv(mover->getBody()->GetLinearVelocity());
			float bodyVelocityAngular = mover->getBody()->GetAngularVelocity();
			/*
			velProj = (vel & pathDir) / |pathDir|
			time = |pathDir| / |velProj| = |pathDir| * |pathDir| / (vel & pathDir)
			*/
			//float distanceLeft = bodyVelocityLinear & pathDir.normalise();
			/*
			float arriveTime = pathDir.length_squared() / (bodyVelocityLinear & pathDir);
			float brakeTime = bodyVelocityLinear.length() / mv->definition->acceleration[0];
			if(arriveTime > 0 && arriveTime < brakeTime)
			{
				preferedSpeed = arriveTime * mv->definition->acceleration[0];
				if(preferedSpeed > maxVelocity) 
					preferedSpeed = maxVelocity;
			}*/
		}
	}
	else
	{
		findMax = false;
		preferedSpeed = 0;													// хотелось бы стоять на месте и не двигаться
		preferedAngle = mover->getGlobalPose().orientation;					// и смотреть в ту же сторону		
	}

	float bestRate = 2 * maxVelocity;				// лучший рейтинг, для начала берём самый худший
	Pose::vec bestVelocity = Pose::vec::zero();		// лучшая скорость
	// choose best segment
	
	::rayCast(velocitySpace,preferedAngle,steps,rays);

	/*
	сначала отсечь всё промежутком [0,maxVelocity],
	затем надо перебрать все оставшиеся промежутки, и выбрать
	максимальную границу.
	*/
	std::vector<float> bestRanges;
	if(findMax)
		getMaxRanges(rays, preferedSpeed, bestRanges);
	else
		getMinRanges(rays, 0, bestRanges);
	/*
	затем выбираем наилучшее направление
	*/
	vec2f preferedVelocity = preferedDirection * preferedSpeed;
	for(int i = 0; i < rays.size();i++)
	{
		float angle = rays[i].first;
		float distance = bestRanges[i];
		if( distance < 0 )
			continue;
		Pose::vec vel = distance * Pose::vec(cosf(angle),sinf(angle));
		float rate = vecDistance(vel, preferedVelocity);
		if(distance > 0 && rate < bestRate)
		{
			bestRate = rate;
			bestVelocity = vel;
		}
	}	

	velocity = bestVelocity;

	float approachTime=2.0;
	float time = timeToImpact();
	if(time<approachTime && time>0)
		velocity*=(time/approachTime);

	const float t = 0.5;	// варьируем инертность объекта. 
	mover->directionControl(velocity, turnOnly ? 0.f : velocity.length());
	//object->newVelocity=object->velocity*(1.f-t)+velocity*t;
}