Example #1
0
/* This function calculates any maneuvers that are necessary for the 
current plane to avoid looping. Returns a waypoint based on calculations. 
If no maneuvers are necessary, then the function returns the current 
destination. */
sim::waypoint sim::takeDubinsPath(PlaneObject &plane1) {
    
	/* Initialize variables */
	sim::coordinate circleCenter;
	sim::waypoint wp = plane1.getDestination();
	double minTurningRadius = 0.75*MINIMUM_TURNING_RADIUS;
	bool destOnRight;
    
	/* Calculate cartesian angle from plane to waypoint */
	double wpBearing = findAngle(plane1.getCurrentLoc().latitude, 
		plane1.getCurrentLoc().longitude, wp.latitude, wp.longitude);
    
	/* Calculate cartesian current bearing of plane (currentBearing is stored as Cardinal) */
	double currentBearingCardinal = plane1.getCurrentBearing();	
	double currentBearingCartesian = toCartesian(currentBearingCardinal);
	
	if (fabs(currentBearingCardinal) < 90.0)
	/* Figure out which side of the plane the waypoint is on */		
		destOnRight = ((wpBearing < currentBearingCartesian) && 
                       (wpBearing > manipulateAngle(currentBearingCartesian - 180.0)));
	else
		destOnRight = !((wpBearing > currentBearingCartesian) && 
                        (wpBearing < manipulateAngle(currentBearingCartesian - 180.0)));
        
	/* Calculate the center of the circle of minimum turning radius on the side that the waypoint is on */
	circleCenter = calculateLoopingCircleCenter(plane1, minTurningRadius, destOnRight);

	/* If destination is inside circle, must fly opposite direction before we can reach destination */
	if (findDistance(circleCenter.latitude, circleCenter.longitude, wp.latitude, wp.longitude) < 
			minTurningRadius)
		return calculateWaypoint(plane1, minTurningRadius, !destOnRight);
	else
		return wp;
}
Example #2
0
/*
Given a waypoint (latitude, longitude, and altitude) as well as the bearing and angular distance to travel,
calculateCoordinate will return the new location in the form of a waypoint.
*/
AU_UAV_ROS::waypoint calculateCoordinate(AU_UAV_ROS::waypoint currentPosition, double bearing, double distance){
	// Calculate final latitude and longitude; see movable-type.co.uk/scripts/latlong.html for more detail
	bearing *= DEGREES_TO_RADIANS; // convert angle of force to radians

	double lat1 = currentPosition.latitude*DEGREES_TO_RADIANS; // lat1 = current latitude in radians
	double dLat = distance*cos(bearing); // calculate change in latitude
	double lat2 = lat1 + dLat; // calculate final latitude
	double dPhi = log(tan(lat2/2+PI/4)/tan(lat1/2+PI/4));
	double q = (!(dPhi < 0.0001)) ? dLat/dPhi : cos(lat1);  // East-West line gives dPhi=0
	double dLon = distance*sin(bearing)/q; // calculate change in longitude
	
	// check for some daft bugger going past the pole, normalise latitude if so
	if (abs(lat2) > PI/2) 
		lat2 = lat2>0 ? PI-lat2 : -(PI-lat2);
	
	double lon2 = (currentPosition.longitude*DEGREES_TO_RADIANS+dLon) * RADIANS_TO_DEGREES; // calculate final latitude and convert to degrees

	//wrap around if necessary to ensure final longitude is on the interval [-180, 180]
	lon2 = manipulateAngle(lon2);

	lat2 *= RADIANS_TO_DEGREES; // convert final latitude to degrees

	AU_UAV_ROS::waypoint coordinate;
	coordinate.latitude = lat2;
	coordinate.longitude = lon2;
	coordinate.altitude = currentPosition.altitude;
	
	return coordinate;
}
Example #3
0
//This will take two waypoints and measure the heading between them (based on position)
//This is an estimation of plane heading based on the position heading from a point a time t and time t-1
//waypoints must be in meters
//A zero degree heading points directly North (and East is 90 degrees and West is -90 degrees to keep in [-180,180] range)
double getNewHeading(AU_UAV_ROS::position first, AU_UAV_ROS::position second)
{
    double deltaX = second.x_coordinate - first.x_coordinate;
	double deltaY = second.y_coordinate - first.y_coordinate;
	double heading = atan2(deltaX,deltaY);
    
	heading = (heading*RADIANS_TO_DEGREES);
    heading = manipulateAngle(heading);
    
	return heading;
}
Example #4
0
/* Convert angle in the Cartesian plane to a Cardinal direction */
double toCardinal(double angle){
	angle = manipulateAngle(angle); /* get angle on the interval [-180, 180] */

	if (angle <= 90 && angle >= -90) /* angle is in the first or fourth quadrant */
		return 90 - angle;
	else if (angle >= 90 && angle <= 180) /* angle is in the second quadrant */
		return -1*angle + 90;
	else if (angle <= -90 && angle >= -180) /* angle is in third quadrant */
		return -180 + -1*(90 + angle);
	else 
		return -999; /* should never happen in current setup */ 
}
Example #5
0
/* Convert Cardinal direction to an angle in the Cartesian plane */
double toCartesian(double UAVBearing){
	UAVBearing = manipulateAngle(UAVBearing); /* get angle on the interval [-180, 180] */

	if (UAVBearing < 180 && UAVBearing >= 0) /* UAV bearing is in the first or fourth quadrant */
		return 90 - UAVBearing;
	else if (UAVBearing < 0 && UAVBearing >= -90) /* UAV bearing is in the second quadrant */
		return -1*UAVBearing + 90;
	else if (UAVBearing < -90 && UAVBearing > -180) /* UAV bearing is in the third quadrant */
		return -1*(UAVBearing + 180) - 90;
	else if (UAVBearing == 180 || UAVBearing == -180)
		return -90;
	else
		return -999; /* should never happen in current setup */
}