User:Pedersen/Code Samples/Radar

From Robowiki
< User:Pedersen‎ | Code Samples
Revision as of 19:02, 11 January 2008 by Pedersen (talk | contribs) (migration)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

package pedersen.systems;

I have developed three modes of radar operation, used under various circumstances.

  • Passive Mode: sweeps a tiny arc forward of the tank.
  • Duel Mode: sweeps full circle until a target is aquired, then locks on the target with a rather small arc, which scales to the distance from the enemy.
  • Melee Mode: sweeps full circle until a target is aquired, temporarily locking on the target in a wide arc, and periodically circle sweeping afteward.

The three share an interface and a base class.


/**
 * Common interface for all scanning methods.
 */
public interface ScanningMethod
{
	//:://////////////////////////////////////
	//::  Methods
	//:://////////////////////////////////////
	
	/**
	 * Operates the scanner.
	 * 
	 * @param absoluteHeading the present scanner heading
	 * @param projectedPosition the projected scanner position
	 * @param target the present target lock
	 * 
	 * @return the relative heading change as a result of the operation
	 */
	public double operate( double absoluteHeading,  Vehicle projectedPosition, Target target );
	
	//:://////////////////////////////////////
	//::  Static Constants
	//:://////////////////////////////////////
	
	public static final double maximumRateOfRelativeRotation = Math.PI / 4.0; // 45 degrees
}

/**
 * Common base class for all scanning methods.
 */
public class ScanningMethodBase
{
	//:://////////////////////////////////////
	//::  Methods
	//:://////////////////////////////////////
	
	/**
	 * Instructs a scanner to move to an angle offset beyond a heading.  
	 * Subsequent scans flip to the other side of the heading.
	 * 
	 * @param scanner the scanner to instruct
	 * @param heading the mean scan heading
	 * @param sweepAngle the angle to sweep to either side of the mean scan heading
	 */
	protected void sweep( DynamicHeading scanner, double heading, double sweepAngle )
	{
		scanner.setAbsoluteTargetHeading( heading + ( sweepAngle * ( -0.5 + scanIndex % 2 ) ) );
	}
	
	//:://////////////////////////////////////
	//::  Instance Variables
	//:://////////////////////////////////////
	
	protected static long scanIndex = 0;
}

/**
 * Scanning Methods for locking onto a target until it is destroyed.
 * Until a target is aquired, the scanner sweeps clockwise indefinitely.
 */
public class ScanningMethodLockImpl extends ScanningMethodBase implements ScanningMethod
{
	//:://////////////////////////////////////
	//::  Methods
	//:://////////////////////////////////////

	/**
	* Operates the scanner.
	* 
	* @param absoluteHeading the present scanner heading
	* @param projectedPosition the projected scanner position
	* @param target the present target lock
	* @return the relative heading change as a result of the operation
	*/
	public double operate( double absoluteHeading, Vehicle projectedPosition, Target target )
	{
		DynamicHeading scanner = new DynamicHeadingImpl( maximumRateOfRelativeRotation );
		scanner.setHeading( absoluteHeading );

		scanIndex++;

		if( target == null )
		{
			scanner.setRelativeTargetHeading( maximumRateOfRelativeRotation );
		}
		else
		{
			double targetScanNarrow = 2.0 * Math.atan( Vehicle.maximumAbsVelocity / projectedPosition.getDistance( target ) );
			this.sweep( scanner, projectedPosition.getBearing( target ).getHeading(), targetScanNarrow );
		}

		return scanner.compare( new StaticHeadingImpl( scanner.projectHeading() ) );
	}
}

/**
 * Scanning Methods for sweeping a tiny arc to the front.
 * This is fluff radar mode for end of round victory dances, etc.
 */
public class ScanningMethodPassiveImpl extends ScanningMethodBase implements ScanningMethod
{
	//:://////////////////////////////////////
	//::  Methods
	//:://////////////////////////////////////

	/**
	* Operates the scanner.
	* 
	* @param absoluteHeading the present scanner heading
	* @param projectedPosition the projected scanner position
	* @param target the present target lock
	* @return the relative heading change as a result of the operation
	*/
	public double operate( double absoluteHeading, Vehicle projectedPosition, Target target )
	{
		DynamicHeading scanner = new DynamicHeadingImpl( maximumRateOfRelativeRotation );
		scanner.setHeading( absoluteHeading );

		scanIndex++;

		this.sweep( scanner, projectedPosition.getHeading(), targetScanOff );

		return scanner.compare( new StaticHeadingImpl( scanner.projectHeading() ) );
	}

	//:://////////////////////////////////////
	//::  Static Constants
	//:://////////////////////////////////////

	private static final double targetScanOff = 0.00001;
}

/**
 * Scanning Methods for situational awareness.
 * Until a target is aquired, the scanner sweeps clockwise indefinitely.
 * After a target is aquired, the scanner is semi-locked in a wide arc, periodically rescanning the environment.
 */
public class ScanningMethodStandardImpl extends ScanningMethodBase implements ScanningMethod
{
	//:://////////////////////////////////////
	//::  Methods
	//:://////////////////////////////////////

	/**
	 * Operates the scanner.
	 * 
	 * @param absoluteHeading the present scanner heading
	 * @param projectedPosition the projected scanner position
	 * @param target the present target lock
	 * @return the relative heading change as a result of the operation
	 */
	public double operate( double absoluteHeading, Vehicle projectedPosition, Target target )
	{
		DynamicHeading scanner = new DynamicHeadingImpl( maximumRateOfRelativeRotation );
		scanner.setHeading( absoluteHeading );

		if( scanIndex++ > scanCycle) this.resetScanCycle( );
		if( ( target == null ) || ( scanIndex < scanSweepCycle ) )
		{
			scanner.setRelativeTargetHeading( maximumRateOfRelativeRotation );
		}
		else
		{
			this.sweep( scanner, projectedPosition.getBearing( target ).getHeading(), targetScanWide );
		}

		return scanner.compare( new StaticHeadingImpl( scanner.projectHeading() ) );
	}


	/**
	 * Resets the scan cycle index, forcing an immediate sweep and a fresh delay for the recurring sweep.
	 */
	private void resetScanCycle( )
	{
		scanIndex = 0;
	}

	//:://////////////////////////////////////
	//::  Static Constants
	//:://////////////////////////////////////

	private static final double targetScanWide = maximumRateOfRelativeRotation;
	private static final long scanSweepCycle = 8;
	private static final long scanCycle = 40;
}

The scan cycle reset method could be moved into the base class and exposed through the interface so that it can be called when taking an actual shot.