Difference between revisions of "User:Pedersen/Code Samples/Radar"

From Robowiki
Jump to navigation Jump to search
(migration)
 
m (Using <syntaxhighlight>.)
 
Line 13: Line 13:
 
<hr>
 
<hr>
  
<pre>
+
<syntaxhighlight>
 
/**
 
/**
 
  * Common interface for all scanning methods.
 
  * Common interface for all scanning methods.
Line 200: Line 200:
 
private static final long scanCycle = 40;
 
private static final long scanCycle = 40;
 
}
 
}
</pre>
+
</syntaxhighlight>
  
 
<hr>
 
<hr>
  
 
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.
 
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.

Latest revision as of 09:37, 1 July 2010

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.