/** test the string swapping */ public void testSubstitution() { final String sample = "eerrt$BRG$sdfsdfs$RNG$sdf<TargetType/>sdd"; final String answer = "eerrt2.1sdfsdfs12.1sdf<TargetType><Type Name=\"RED\"/></TargetType>sdd"; final WorldDistance rng = new WorldDistance(12.1, WorldDistance.YARDS); final Float brg = new Float(2.1f); final CoreSensor sensor = new ASSET.Models.Sensor.Initial.OpticSensor(12); final NetworkParticipant host = new ASSET.Models.Vessels.SSK(12); final NetworkParticipant target = new ASSET.Models.Vessels.Surface(22); final DetectionEvent de = new DetectionEvent( 0, host.getId(), null, sensor, rng, rng, brg, null, null, null, null, null, target); final TargetType getRed = new TargetType(); getRed.addTargetType(Category.Force.RED); final WorldLocation currentLocation = new WorldLocation(1, 1, 0); final Status currentStatus = new Status(12, 2000); currentStatus.setLocation(currentLocation); final String res = LaunchWeapon.swapKeywords(de, currentStatus, sample, getRed); assertEquals("strings swapped", answer, res); }
/** test we can read the weapon from file */ public void testReadWeapon() { final WorldDistance rng = new WorldDistance(12.1, WorldDistance.YARDS); final Float brg = new Float(2.1f); final CoreSensor sensor = new ASSET.Models.Sensor.Initial.OpticSensor(12); final NetworkParticipant host = new ASSET.Models.Vessels.SSK(12); final NetworkParticipant target = new ASSET.Models.Vessels.Surface(22); final DetectionEvent de = new DetectionEvent( 0, host.getId(), null, sensor, rng, rng, brg, null, null, null, null, null, target); final WorldLocation currentLocation = new WorldLocation(1, 1, 0); final Status currentStatus = new Status(12, 2000); currentStatus.setLocation(currentLocation); final ParticipantType newPart = LaunchWeapon.getWeapon(de, currentStatus, launchBehaviour, null); assertNotNull("participant created", newPart); final DecisionType dt = newPart.getDecisionModel(); assertEquals("correct model loaded", "Waterfall", dt.getName()); System.out.println("part created"); }
/** do the actual launch */ private void launchWeapon( final DetectionEvent detection, final ASSET.Scenario.ScenarioActivityMonitor monitor, final Status currentLocation, final double initial_course_degs, final long time) { // have we read in the weapon description yet? if ((_launchThis == null) || (_launchThis.length() == 0)) _launchThis = readWeaponFromThisFile(this._fileName); final ParticipantType newPart = getWeapon(detection, currentLocation, _launchThis, _myTarget); // create the target monitor.createParticipant(newPart); // set it's status final Status newState = new Status(currentLocation); // update the status for the object's new id newState.setId(newPart.getId()); // and put it in the participant newPart.setStatus(newState); // give it a faster speed though newState.setSpeed(new WorldSpeed(30, WorldSpeed.M_sec)); // give the weapon a hint about direction to travel in SimpleDemandedStatus ds = new SimpleDemandedStatus(time, newState); ds.setCourse(initial_course_degs); newPart.setDemandedStatus(ds); }
public void testTheMove() { // ok, create some locations WorldLocation locA = new WorldLocation(0, 0, 12); WorldLocation locC = new WorldLocation(0, 3, 12); Move move = new Move(); move.setCourse(new Double(60)); move.setSpeed(new WorldSpeed(12, WorldSpeed.M_sec)); move.setDistance(new WorldDistance(3, WorldDistance.DEGS)); // check the initial values are correct assertEquals("the course is set", move.getCourse().doubleValue(), 60, 0.01); assertEquals("the speed is set", move.getSpeed().getValueIn(WorldSpeed.M_sec), 12, 0.01); assertEquals( "the distance is set", move.getDistance().getValueIn(WorldDistance.DEGS), 3, 0.01); // change course to head east (to ease our testing) move.setCourse(new Double(90)); Status theStat = new Status(12, 12000); theStat.setLocation(locA); theStat.setSpeed(new WorldSpeed(12, WorldSpeed.Kts)); DemandedStatus res = move.decide(theStat, null, null, null, null, 1000); // did it work? assertEquals("course set correctly", ((SimpleDemandedStatus) res).getCourse(), 90, 0.01); assertEquals("speed set correctly", ((SimpleDemandedStatus) res).getSpeed(), 12, 0.01); assertEquals("depth not set", ((SimpleDemandedStatus) res).getHeight(), -12, 0.01); assertEquals( "target location set correctly", move._theDestination.subtract(locC).getRange(), 0, 0.001); // fiddle with the depth move.setHeight(new WorldDistance(-55, WorldDistance.METRES)); res = move.decide(theStat, null, null, null, null, 1000); // did it work? assertEquals("course set correctly", ((SimpleDemandedStatus) res).getCourse(), 90, 0.01); assertEquals("speed set correctly", ((SimpleDemandedStatus) res).getSpeed(), 12, 0.01); assertEquals("depth set", ((SimpleDemandedStatus) res).getHeight(), -55, 0.01); }
/** * note that our parent behaviour has been interrupted. If we have a calculated the time/distance * to the next waypoint these calculations may become invalid - we need to clear them in order * that they be re-calculated next time we actually get called. On being interrupted we will * remember the location so we can head back to it before getting back on our proper route * * @param currentStatus */ public void routeInterrupted(Status currentStatus) { // have we already been interrupted? if (_interruptedLocation == null) { // ok, remember where we are _interruptedLocation = new WorldLocation(currentStatus.getLocation()); } else { // we've already been interrupted. we want to head back to that original location, not // another. } // whatever, we want to forget any immediate route calculations we may have forgetCalculatedRoute(); }
/** * process a turn component of a larger manoeuvre * * @param turnRequired how far we have to turn (-ve is left) * @param moves the movement chars for this participant * @param current the current status * @param endTime the end time for this step * @param turner the turn algorithm we're using * @param demandedHeight the demanded height (normally the same as the current height - to * maintain height (and therefore speed) in a manoeuvre. * @return */ protected Status doThisPartOfTheTurn( double turnRequired, MovementCharacteristics moves, Status current, long endTime, TurnAlgorithm turner, double demandedHeight) { // what's our turn rate? double turnRate = DirectedOnTopWaypoint.getTurnRateFor( moves, current.getSpeed().getValueIn(WorldSpeed.M_sec)); turnRate = MWC.Algorithms.Conversions.Rads2Degs(turnRate); // hmm, so how long will it take? long turnTime = (long) (Math.abs(turnRequired) / turnRate * 1000d); // hey, trim the turn time to the remaining time long thisStep = endTime - current.getTime(); turnTime = Math.min(turnTime, thisStep); // now, to make sure we turn the right way, we're going to turn 1/2 way first, then the second // part double semiTurn = turnRequired / 2; double semiTurnTime = turnTime / 2; // hey, make sure we at least have a step to make! semiTurnTime = Math.max(1, semiTurnTime); // amd do the turn! SimpleDemandedStatus sds = new SimpleDemandedStatus(1, (long) (current.getTime() + (semiTurnTime))); sds.setCourse(current.getCourse() + semiTurn); sds.setSpeed(current.getSpeed()); sds.setHeight(demandedHeight); current = turner.doTurn(current, sds, moves, sds.getTime()); // and the second part of the turn! sds = new SimpleDemandedStatus(1, current.getTime() + (long) (turnTime - semiTurnTime)); sds.setCourse(current.getCourse() + semiTurn); sds.setSpeed(current.getSpeed()); sds.setHeight(demandedHeight); current = turner.doTurn(current, sds, moves, sds.getTime()); return current; }
public MovedEvent(final Status status) { super(status.getTime()); _status = status; }
protected static Status processStraightCourse( Double requiredDistance, Status current, long endTime, HighLevelDemandedStatus highLevelDemStat, TurnAlgorithm turner, MovementCharacteristics moves) { // How far do we still have to go? double straightDistance = requiredDistance.doubleValue(); // how far will we travel in this time step? // hey, how long of the time step is remaining? long thisTimeStep = endTime - current.getTime(); // do we have a demanded height change ('cos this really buggers things up) double demHeight = -highLevelDemStat.getCurrentTarget().getDepth(); double curHeight = -current.getLocation().getDepth(); WorldLocation origin = new WorldLocation(current.getLocation()); // take note of the original height. We may change height during a height change, but wish to // return to the original // height on completion. Alternatively we may wish to change to a demanded speed on completion // of the height change WorldSpeed originalSpeed = null; if (demHeight != curHeight) { // ok, and is there any distance remaining? double distanceTravelled = current.getLocation().subtract(origin).getRange(); distanceTravelled = MWC.Algorithms.Conversions.Degs2m(distanceTravelled); double distanceRemaining = straightDistance - distanceTravelled; if (distanceRemaining > 0.1) { // yup, let's continue // yup, height change there is... double heightDelta = demHeight - curHeight; // find out what the height change speed is double stepTime = (endTime - current.getTime()) / 1000d; // and how long will the height change take? long heightChangeTimeMillis = (long) (TurnAlgorithm.calcHeightChangeTime(heightDelta, moves, stepTime) * 1000d); // WORKAROUND - a very small height change may require a time less than one millisecond - // represented // as zero time. If this is the case, give us a tiny time step if (heightChangeTimeMillis == 0) heightChangeTimeMillis = 1; // hey, trim the height change to our remaining time heightChangeTimeMillis = Math.min(heightChangeTimeMillis, thisTimeStep); long timeTakenMillis; // right then. Is this a vehicle with standard climb and dive speeds? if (moves instanceof ClimbRateCharacteristics) { // yes, we need to factor in the speed change // ok, we're doing a height change with speed consequences. remember the current speed, // so // we can return to it on completion originalSpeed = new WorldSpeed(current.getSpeed()); // ok, how far will we travel during this period timeTakenMillis = DirectedOnTopWaypoint.calcClippedHeightChangeTimeFor( current.getSpeed(), heightDelta, moves, heightChangeTimeMillis, distanceRemaining); // todo - double-check that height change is achievable in the time-step, // though the turn decision algorithm should only produce achievable height changes } else { // right, we're just going to travel at normal speed for the turn. // calc how far we are due to travel in the time step // how long will it take to cover the remaining distance at this speed timeTakenMillis = (long) (1000 * straightDistance / current.getSpeed().getValueIn(WorldSpeed.M_sec)); } // trim to the step time timeTakenMillis = Math.min(heightChangeTimeMillis, timeTakenMillis); // and create a demanded status SimpleDemandedStatus sds = new SimpleDemandedStatus(1, current); // and set the height sds.setHeight(demHeight); // and do the step current = turner.doTurn(current, sds, moves, current.getTime() + timeTakenMillis); } // if we have distance to run } // that's the height change done - we should be at our demanded height now. If there's any time // left we will allow // a speed change // ok, height change is done. Is there any time left? if (current.getTime() < endTime) { // ok, and is there any distance remaining? double distanceTravelled = current.getLocation().subtract(origin).getRange(); distanceTravelled = MWC.Algorithms.Conversions.Degs2m(distanceTravelled); double distanceRemaining = straightDistance - distanceTravelled; if (distanceRemaining > 0.1) { // yup, let's continue // is there a demanded speed change? WorldSpeed demSpeedObj = highLevelDemStat.getSpeed(); if (demSpeedObj != null) { double demSpeed = demSpeedObj.getValueIn(WorldSpeed.M_sec); double curSpeed = current.getSpeed().getValueIn(WorldSpeed.M_sec); if (curSpeed != demSpeed) { // ok, process the speed change long remainingTime = endTime - current.getTime(); boolean isAccelerating = TurnAlgorithm.areWeAccelerating(curSpeed, demSpeed); WorldAcceleration accelRate = TurnAlgorithm.calcAccelRate(isAccelerating, moves); long timeAllowed = DirectedOnTopWaypoint.calcTrimmedAccelTime( demSpeedObj, current.getSpeed(), accelRate, remainingTime, distanceRemaining); // and move us forward SimpleDemandedStatus sds = new SimpleDemandedStatus(1, current); // and set the speed sds.setSpeed(demSpeedObj); // and do the step current = turner.doTurn(current, sds, moves, current.getTime() + timeAllowed); } // if we need a speed change } // if we have a demanded speed else { // hey, no demanded speed change. Was there a dem height change? // This may have caused a speed change which we now need to counter if (originalSpeed != null) { // yup, we changed height. We need to head back to the old speed // ok, process the speed change long remainingTime = endTime - current.getTime(); boolean isAccelerating = TurnAlgorithm.areWeAccelerating(current.getSpeed(), originalSpeed); WorldAcceleration accelRate = TurnAlgorithm.calcAccelRate(isAccelerating, moves); long timeAllowed = DirectedOnTopWaypoint.calcTrimmedAccelTime( current.getSpeed(), current.getSpeed(), accelRate, remainingTime, distanceRemaining); // long timeAllowed = DirectedOnTopWaypoint.calcTrimmedAccelTime(demSpeedObj, // current.getSpeed(), // accelRate, remainingTime, distanceRemaining); // and move us forward SimpleDemandedStatus sds = new SimpleDemandedStatus(1, current); // and do the step current = turner.doTurn(current, sds, moves, current.getTime() + timeAllowed); } } } // if we have distance to run } // if there is time left // hmm, that's the speed change over. do we have any time left? if (current.getTime() < endTime) { // how far have we travelled double distanceTravelled = current.getLocation().subtract(origin).getRange(); distanceTravelled = MWC.Algorithms.Conversions.Degs2m(distanceTravelled); // which leaves how far? double distanceRemaining = straightDistance - distanceTravelled; if (distanceRemaining > 0.1) { // yup, let's continue travelling in a straight line at steady speed/height // collate the input data. // how long will it take to cover the remaining distance at this speed long timeTakenMillis = (long) (1000 * straightDistance / current.getSpeed().getValueIn(WorldSpeed.M_sec)); // trim to the step time timeTakenMillis = Math.min(thisTimeStep, timeTakenMillis); // and create a demanded status SimpleDemandedStatus sds = new SimpleDemandedStatus(1, current); // and do the step current = turner.doTurn(current, sds, moves, current.getTime() + timeTakenMillis); } } return current; }
// TODO FIX-TEST public void NtestLaunch() { final double rngToHim = 5000; final double crseToHim = 45; final WorldLocation origin = new WorldLocation(0, 0, 0); final WorldLocation hisLoc = origin.add( new WorldVector( MWC.Algorithms.Conversions.Degs2Rads(crseToHim), MWC.Algorithms.Conversions.Yds2Degs(rngToHim), 0)); final Status blueStat = new Status(13, 0); blueStat.setLocation(origin); blueStat.setCourse(0); blueStat.setSpeed(new WorldSpeed(4, WorldSpeed.M_sec)); final Status redStat = new Status(blueStat); redStat.setLocation(hisLoc); // setup a couple of targets final ASSET.Models.Vessels.SSN ssn = new ASSET.Models.Vessels.SSN(1); ssn.setName("ssn"); ssn.setMovementChars( SSMovementCharacteristics.generateDebug("scrap", 1, 1, 0, 20, 1, 300, 1, 1, 10, 100)); ssn.setCategory( new ASSET.Participants.Category( Category.Force.BLUE, Category.Environment.SUBSURFACE, Category.Type.SUBMARINE)); ssn.setStatus(blueStat); final ASSET.Models.Sensor.Initial.OpticSensor periscope = new ASSET.Models.Sensor.Initial.OpticSensor(12); ssn.addSensor(periscope); RadiatedCharacteristics rc = new RadiatedCharacteristics(); rc.add(EnvironmentType.VISUAL, new Optic(12, new WorldDistance(12, WorldDistance.METRES))); ssn.setRadiatedChars(rc); final ASSET.Models.Vessels.Surface su = new ASSET.Models.Vessels.Surface(4); su.setName("su"); su.setMovementChars( SurfaceMovementCharacteristics.generateDebug("scrap", 1, 1, 0.001, 14, 1, 299)); su.setCategory( new ASSET.Participants.Category( Category.Force.RED, Category.Environment.SURFACE, Category.Type.CARRIER)); su.setStatus(redStat); rc = new RadiatedCharacteristics(); rc.add(EnvironmentType.VISUAL, new Optic(12, new WorldDistance(12, WorldDistance.METRES))); su.setRadiatedChars(rc); /** create the scenario */ final CoreScenario scenario = new CoreScenario(); scenario.setScenarioStepTime(10000); scenario.setTime(0); scenario.setName("Testing weapon launch"); // get somebody to listen to the tracks final ASSET.Scenario.Observers.Recording.DebriefReplayObserver debrief_writer = new ASSET.Scenario.Observers.Recording.DebriefReplayObserver( "�test_reports", null, true, "test observer", true); debrief_writer.setup(scenario); // DON'T BOTHER RECORDING JUST YET! debrief_writer.setActive(false); /** now the behaviours */ final Trail trailRed = new Trail(new WorldDistance(2000, WorldDistance.YARDS)); final TargetType getRed = new TargetType(); getRed.addTargetType(Category.Force.RED); trailRed.setTargetType(getRed); final LaunchWeapon launchWeapon = new LaunchWeapon(); launchWeapon.setTargetType(getRed); launchWeapon.setLaunchRange(new WorldDistance(4000, WorldDistance.YARDS)); launchWeapon.setCoolOffTime(new Duration(Duration.DAYS, 3)); // 24 hr cool off time launchWeapon.setLaunchType(launchBehaviour); final Waterfall blueWaterfall = new Waterfall(); blueWaterfall.insertAtFoot(trailRed); blueWaterfall.insertAtHead(launchWeapon); ssn.setDecisionModel(blueWaterfall); scenario.addParticipant(1, ssn); scenario.addParticipant(4, su); // move forward a while boolean found = false; double lastRange = -1; double thisRange = -1; int counter = 0; while (!found && counter <= 100000) { scenario.step(); final WorldVector sep = ssn.getStatus().getLocation().subtract(su.getStatus().getLocation()); thisRange = MWC.Algorithms.Conversions.Degs2Yds(sep.getRange()); if (lastRange == -1) { lastRange = thisRange; } if (ssn.getActivity().equals(LaunchWeapon.LAUNCH_MESSAGE)) { found = true; System.out.println("LAUNCHED"); } else { lastRange = thisRange; } // just do "MAD" check to ensure we don't go on for ever counter++; } // check we didn't time out assertTrue(" we just ran to end of loop (no fire)", counter < 100000); // check we launched at the right point final double launchYds = launchWeapon.getLaunchRange().getValueIn(WorldDistance.YARDS); assertTrue("didn't fire too soon", lastRange > launchYds); assertTrue( "didn't fire too late, got:" + launchYds + " but wanted:" + thisRange, thisRange <= launchYds); // so, we've launched the weapon - see how many participants are in the scenario assertEquals("New participant created", 3, scenario.getListOfParticipants().length); // find the weapon // final ParticipantType torpedo = // scenario.getThisParticipant(scenario.getListOfParticipants()[0].intValue()); // check if the torpedo gets to the target while (scenario.getListOfParticipants().length == 3) { scenario.step(); } // check that the torpedo destroys the SU, and they are both removed assertEquals("surface participant destroyed", 1, scenario.getListOfParticipants().length); // move a bit further just to give us some more blue track for (int ii = 0; ii < 20; ii++) { scenario.step(); } }
/** put our keywords into the XML description */ protected static String swapKeywords( final DetectionEvent detection, final Status currentLocation, final String weapon, final TargetType theTarget) { // amend string template to include available parameters final Float brg_degs = detection.getBearing(); final WorldDistance rng = detection.getRange(); // take a copy of the string String working = new String(weapon); // swap the bearing if (brg_degs != null) { final String brg_val = "" + brg_degs.floatValue(); working = replaceAll(working, "$BRG$", brg_val); } // swap the range if (rng != null) { final String rng_val = "" + rng.getValueIn(WorldDistance.YARDS); working = replaceAll(working, "$RNG$", rng_val); } // insert the location of the target if (brg_degs != null) { final float brg_val = brg_degs.floatValue(); // do we know range? if (rng != null) { // yes, compute target location final WorldVector newVector = new WorldVector( MWC.Algorithms.Conversions.Degs2Rads(brg_val), rng.getValueIn(WorldDistance.DEGS), 0); final WorldLocation newLoc = currentLocation.getLocation().add(newVector); // produce strings from this location final String theDepth = "" + newLoc.getDepth(); final String theLat = "" + newLoc.getLat(); final String theLong = "" + newLoc.getLong(); // put these strings into the new behaviour working = replaceAll(working, "$TGT_DEPTH$", theDepth); working = replaceAll(working, "$TGT_LAT$", theLat); working = replaceAll(working, "$TGT_LONG$", theLong); } else { // no, send the weapon down a bearing for XXXX yds // compute target location final double TGT_RANGE = 5000; final WorldVector newVector = new WorldVector( MWC.Algorithms.Conversions.Degs2Rads(brg_val), MWC.Algorithms.Conversions.Yds2Degs(TGT_RANGE), 0); final WorldLocation newLoc = currentLocation.getLocation().add(newVector); // produce strings from this location final String theDepth = "" + newLoc.getDepth(); final String theLat = "" + newLoc.getLat(); final String theLong = "" + newLoc.getLong(); // put these strings into the new behaviour working = replaceAll(working, "$TGT_DEPTH$", theDepth); working = replaceAll(working, "$TGT_LAT$", theLat); working = replaceAll(working, "$TGT_LONG$", theLong); } } if (theTarget != null) { // output the XML header stuff // output the plot final java.io.StringWriter newString = new StringWriter(); // final com.sun.xml.tree.XmlDocument doc = new com.sun.xml.tree.XmlDocument(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); Document doc = null; try { DocumentBuilder builder = factory.newDocumentBuilder(); doc = builder.newDocument(); final org.w3c.dom.Element type = ASSET.Util.XML.Decisions.Util.TargetTypeHandler.getElement(theTarget, doc); doc.appendChild(type); doc.setNodeValue(type.getTagName()); // doc.changeNodeOwner(type); // doc.setSystemId("ASSET XML Version 1.0"); // Use a Transformer for output TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer transformer = tFactory.newTransformer(); DOMSource source = new DOMSource(doc); StreamResult result = new StreamResult(newString); transformer.transform(source, result); } catch (ParserConfigurationException e) { e.printStackTrace(); // To change body of catch statement use Options | File Templates. } catch (DOMException e) { e.printStackTrace(); // To change body of catch statement use Options | File Templates. } catch (TransformerFactoryConfigurationError transformerFactoryConfigurationError) { transformerFactoryConfigurationError .printStackTrace(); // To change body of catch statement use Options | File Templates. } catch (TransformerException e) { e.printStackTrace(); // To change body of catch statement use Options | File Templates. } // // ok, we should be done now // try // { // doc.write(newString); // } // catch(java.io.IOException e) // { // e.printStackTrace(); // } // try to extract the <target type portion if (newString != null) { final String val = newString.toString(); final String startIdentifier = "<TargetType"; final String endIdentifier = "</TargetType"; final int start = val.indexOf(startIdentifier); final int end = val.lastIndexOf(endIdentifier); final String detail = val.substring(start, end + endIdentifier.length() + 1); // lastly, replace the string working = replaceAll(working, "<TargetType/>", detail); } } return working; }
/** * decide the course of action to take, or return null to no be used * * @param status the current status of the participant * @param detections the current list of detections for this participant * @param time the time this decision was made */ public DemandedStatus decide( final Status status, ASSET.Models.Movement.MovementCharacteristics chars, DemandedStatus demStatus, final DetectionList detections, final ASSET.Scenario.ScenarioActivityMonitor monitor, final long time) { // produce a steady-state demanded course - so we continue // what we're doing during the weapons launch DemandedStatus res = null; // clear the activity flag String activity = "Not in trail"; // is it time to fire another yet? if ((_lastLaunch == -1) || (time > _lastLaunch + _coolOffTime.getValueIn(Duration.MILLISECONDS))) { // do we have any detections? if (detections != null) { // get bearing to first detection final int len = detections.size(); if (len > 0) { for (int i = 0; i < len; i++) { final ASSET.Models.Detection.DetectionEvent de = detections.getDetection(i); final Float brg = de.getBearing(); if (brg != null) { // do we have a target type? if (_myTarget != null) { // is this of our target type final ASSET.Participants.Category thisTarget = de.getTargetType(); if (_myTarget.matches(thisTarget)) { // do we have range? if (de.getRange() != null) { // work out distance from us to the target, not from the sensor to the target WorldLocation sensorLocation = de.getSensorLocation(); // Work out the estimated target location WorldVector sensorToTarget = new WorldVector( MWC.Algorithms.Conversions.Degs2Rads(de.getBearing().doubleValue()), de.getRange().getValueIn(WorldDistance.DEGS), 0); WorldLocation targetLocation = sensorLocation.add(sensorToTarget); // how are are we from the target location WorldVector meToTarget = status.getLocation().subtract(targetLocation); double yds_to_target = MWC.Algorithms.Conversions.Degs2Yds(meToTarget.getRange()); double brg_to_target_degs = MWC.Algorithms.Conversions.Rads2Degs(meToTarget.getBearing()); // is it within range? if (yds_to_target < _launchRange.getValueIn(WorldDistance.YARDS)) { // continue in steady state res = new SimpleDemandedStatus(time, status); // remember the launch time _lastLaunch = time; // start the launch steps launchWeapon(de, monitor, status, brg_to_target_degs, time); activity = LaunchWeapon.LAUNCH_MESSAGE; // ok, drop out, we don't need to launch any more weapons return res; } } } } } // if we know the bearing } // looping through the detections } // if we have any detections } // if the detections object was received } // whether it's time to launch another else { // } super.setLastActivity(activity); // always return null, since we continue in steady state return res; }
public DemandedStatus decide( final Status status, ASSET.Models.Movement.MovementCharacteristics chars, DemandedStatus demStatus, ASSET.Models.Detection.DetectionList detections, ASSET.Scenario.ScenarioActivityMonitor monitor, final long time) { // create the output object SimpleDemandedStatus res = null; String thisActivity = null; // have we completed this manoeuvre? if (_transit_complete) { res = null; return res; } // find out where we are WorldLocation currentLoc = status.getLocation(); // are we running towards a destination? if (_theDistance == null) { // ok, we're not heading towards a particular point, just put us onto the correct course and // speed double curSpeed = status.getSpeed().getValueIn(WorldSpeed.M_sec); double curCourse = status.getCourse(); double curHeight = -status.getLocation().getDepth(); thisActivity = ""; // are we already working to a simple demanded course/speed/depth? if (demStatus instanceof SimpleDemandedStatus) { res = new SimpleDemandedStatus(time, (SimpleDemandedStatus) demStatus); } else { res = new SimpleDemandedStatus(time, status); } if (_mySpeed != null) { if (curSpeed != _mySpeed.getValueIn(WorldSpeed.M_sec)) { thisActivity += " speed to:" + (int) _mySpeed.getValueIn(WorldSpeed.Kts); res.setSpeed(_mySpeed.getValueIn(WorldSpeed.M_sec)); } } if (_myCourse != null) { if (curCourse != _myCourse.doubleValue()) { thisActivity += " course to:" + _myCourse.doubleValue(); res.setCourse(_myCourse.doubleValue()); } } if (_myHeight != null) { if (curHeight != _myHeight.getValueIn(WorldDistance.METRES)) { thisActivity += " height to:" + _myHeight.getValueIn(WorldDistance.METRES); res.setHeight(_myHeight.getValueIn(WorldDistance.METRES)); } } // did we update any? if (thisActivity == "") { // no - we must be ok, res = null; } else { // cool, the res is set already } } else { // do we have our destination? if (_theDestination == null) { // no, this is the first time we've been called. Calculate where we're going to WorldVector vector = new WorldVector( MWC.Algorithms.Conversions.Degs2Rads(this._myCourse.doubleValue()), _theDistance.getValueIn(WorldDistance.DEGS), 0); _theDestination = new WorldLocation(currentLoc); _theDestination.addToMe(vector); } else { // ok, we're up and running, have we reached our destination // how far to the target double rngDegs = currentLoc.subtract(_theDestination).getRange(); // and in yards double rngYds = MWC.Algorithms.Conversions.Degs2Yds(rngDegs); if (rngYds < _threshold) { // right, we've got there. Mark complete _transit_complete = true; super.setLastActivity(thisActivity); // and drop out return res; } } // ok, now steer to the destination double brg_rads = _theDestination.subtract(currentLoc).getBearing(); final double brgDegs = MWC.Algorithms.Conversions.Rads2Degs(brg_rads); // and set the course in degs res = new SimpleDemandedStatus(time, status); res.setCourse(brgDegs); // do we have depth? if (_myHeight != null) res.setHeight(_myHeight.getValueIn(WorldDistance.METRES)); // and the speed if (_mySpeed != null) res.setSpeed(_mySpeed.getValueIn(WorldSpeed.M_sec)); thisActivity = "Heading for target location"; } super.setLastActivity(thisActivity); return res; }