diff --git a/scripts/HTN/Trees/Red/ConvoyUnit.xml b/scripts/HTN/Trees/Red/ConvoyUnit.xml index 37b982615b120886dd970c89522c793208286182..e2cea723fe329e357d6b8e235f51fac6f29c4e24 100644 --- a/scripts/HTN/Trees/Red/ConvoyUnit.xml +++ b/scripts/HTN/Trees/Red/ConvoyUnit.xml @@ -81,6 +81,7 @@ goalContainer.getCurrentExecutingStack().addReplanTrigger("GoalTracker_ConvoyPac <Parent>New Node</Parent> <Code IsFile="false">from HTNBehaviors import SendEntityEventDelay +# start the assembly movement printMessage("Assembling...", True) randSpd = state.getLastTriggerParams()[0].get(0) @@ -105,6 +106,7 @@ borg.redUnitStatus[state.getCurrentUnitName()] = 0 from HTNBehaviors import SetRedUnitActivity +# whenever the unit moves this node is what makes it move params = state.getLastTriggerParams()[0] @@ -125,6 +127,7 @@ if attackFlag: borg.redConvoysWaiting[state.getCurrentUnit().getName()].append(info.getMyAssignedName()) +# use the network move tree so the meta terrain functionality is used CreateNetworkMove( state.getCurrentLocation(), wps, @@ -166,6 +169,7 @@ if state.isCommander(): from HTNBehaviors import SendEntityEvent import cxxi.model.behavior.PythonUtilities as PythonUtilities +# used whenver the unit finishes moving (any move) borg.redConvoysWaiting[state.getCurrentUnit().getName()].remove(info.getMyAssignedName()) if len(borg.redConvoysWaiting[state.getCurrentUnit().getName()])==0: @@ -224,6 +228,7 @@ from HTNBehaviors import CreateBasicMove from HTNBehaviors import ConvertToJavaList from HTNBehaviors import SetRedUnitActivity +# start the convoy setup printMessage("Starting convoy setup", True) nlocs = state.getCurrentUnit().getMembers().size() @@ -273,6 +278,7 @@ if state.isCommander(): from HTNBehaviors import SendEntityEventDelay from HTNBehaviors import SetRedUnitActivity +# end the setup process and schedule when to pack up borg.redUnitStatus[state.getCurrentUnitName()] = borg.redUnitStatus[state.getCurrentUnitName()] + 1 setupNum = _gt_activeNode.getVar("setupNum") @@ -323,6 +329,8 @@ if borg.redUnitStatus[state.getCurrentUnitName()]==setupNum: from HTNBehaviors import SendEntityEventDelay from HTNBehaviors import SetRedUnitActivity +# start the pack up process + # commander name cmdName="" if state.isCommander(): @@ -361,6 +369,8 @@ if state.isCommander(): <Code IsFile="false">import cxxi.model.behavior.PythonUtilities as PythonUtilities from HTNBehaviors import SendEntityEventDelay +# complete the packup process + # reset the setup count borg.redUnitStatus[state.getCurrentUnitName()] = 0 @@ -421,7 +431,7 @@ if state.isCommander(): printMessage("Need to return", True) -# TODO: This should probably use the moveToPoint methods +# return to base borg.redUnitStatus[state.getCurrentUnitName()]=0 @@ -471,6 +481,8 @@ if state.isCommander(): from HTNBehaviors import SendEntityEventDelay from HTNBehaviors import SetRedUnitActivity +# tell the RFC we've returned to base and we can be 'reclaimed' (ie, disband the unit and put them back in +# the available entity list) borg.redUnitStatus[state.getCurrentUnitName()] = borg.redUnitStatus[state.getCurrentUnitName()] + 1 #setupNum = _gt_activeNode.getVar("setupNum") diff --git a/scripts/HTN/Trees/Red/RedForceCoordinator.xml b/scripts/HTN/Trees/Red/RedForceCoordinator.xml index 39ed40db13ede538f555d781ad53fd38c7298ea9..6a7184098f1d6bec2a600359821bd27cb192190c 100644 --- a/scripts/HTN/Trees/Red/RedForceCoordinator.xml +++ b/scripts/HTN/Trees/Red/RedForceCoordinator.xml @@ -12,12 +12,14 @@ <Import /> <HTNNode AllowMsg="true" Name="createData" Type="DEFAULT"> <Parent>createRoadNetwork</Parent> - <Code IsFile="false">borg.delay=1 + <Code IsFile="false"># borg values used throughout the scenario +borg.delay=1 borg.redConvoysWaiting=dict() borg.redConvoyDest=dict() borg.redFormsByUnit=dict() borg.redUnitStatus=dict() +# used to keep track of units not assigned to move borg.redWaitingUnits=[] # for logging @@ -178,7 +180,7 @@ printMessage("Created network", True) <Code IsFile="false">import cxxi.model.objects.holders.CMHolder as CMHolder import cxxi.support.types.ControlMeasureType as ControlMeasureType - +# get all way points borg.allWPs = CMHolder.retrieveControlMeasuresByType(ControlMeasureType.WAYPOINT) </Code> <Import /> @@ -188,6 +190,8 @@ borg.allWPs = CMHolder.retrieveControlMeasuresByType(ControlMeasureType.WAYPOINT <Code IsFile="false">import mtry.cxxi.model.HierarchicalTaskNetwork.HTNUtilities as HTNUtilities borg.redEntities = [] +# gather entity data for the scenario + borg.redVehicles = [] borg.redDismounts = [] @@ -552,6 +556,9 @@ if state.getLastTrigger() == "doGoalTracker_StartAttackMove": <Parent>isMoveConvoy</Parent> <Code IsFile="false">import cxxi.model.knowledge.group.holders.NewUnitHolder as NewUnitHolder +# create and start attack move +# heardBefore is used to filter out extra messages (all entities in a unit send this +# message but we only move when we hear it the first time) heardBefore = _gt_activeNode.getVar("heardAttackMsg") if heardBefore == 0: diff --git a/scripts/HTNBehaviors.py b/scripts/HTNBehaviors.py index 8c14fa8d46f8ee6078d3b302765428f044900ed3..e85696dc3509f1d43491c4eadd8bea48b84701d8 100644 --- a/scripts/HTNBehaviors.py +++ b/scripts/HTNBehaviors.py @@ -16,10 +16,13 @@ __NETWORK_MOVE_PATH__ = "HTN/Trees/NetworkMove.xml" borg = None +# creates a way point at the specified entities location (entity is a cxxi entity) def CreateWPAtCurrentLoc(entity): wp = HTNUtilities._py_addControlMeasure(entity.getAssignedName(), entity.getPhysicalState().getGroundTruthLocation()) return wp +# used to calculate if an entity is talking on its radios at whatever time this +# method is called. Not used currently def IsTransmitting(unitName, isCommander): _InitBorgInternal() @@ -39,12 +42,18 @@ def IsTransmitting(unitName, isCommander): else: return False +# sets a red units activity. This is the activity reported in the loggers def SetRedUnitActivity(unitName, activityName): _InitBorgInternal() borg.redUnitActivity[unitName]=activityName borg.redUnitActivityTime[unitName]=Schedule.getSimTime() +# sets a specific entities activity. This is reported in loggers +# Note this is used to create activities for specific entities in a unit +# for example a unit that has only one entity with radar would: +# 1) set the units activity to 'deployed' and the one entity with radar +# could override the 'deployed' status to 'using radar' def SetRedEntityActivityOverride(entityName, activityName): _InitBorgInternal() @@ -72,6 +81,10 @@ def GetRandomChance(probability): int_num = PythonUtilities._py_getRandomNumber("UNIFORM", [0.0, 1.0]) return int_num < probability +# used to initialize the borg in this script. any function that calls +# the borg should call this first to make sure the borg is available +# this is used to overcome some jython/python/cxxi shortcomings +# you don't normally need to do this in a python script def _InitBorgInternal(): global borg @@ -82,16 +95,26 @@ def _InitBorgInternal(): borg = HTNBorg() print "Borg created" +# test the borg is available def TestBorg(): _InitBorgInternal() print "Test borg=",borg.allWPs.size() +# gets a random whole number between minNum and maxNum (inclusive) +# the value is rounded before returning to make sure that +# small and large random vars return min and max (without +# that those values become extremely rare as only a random +# value of 0 or 1 would generate them +# also note this uses the cxxi random stream so its safe to call inside +# behaviors def GetRandomInt(minNum, maxNum): int_num = PythonUtilities._py_getRandomNumber("UNIFORM", [0.0, 1.0]) len = maxNum - minNum size = round(int_num * len) + minNum return size +# convenience method to convert a python list into a randomized java list +# safe to call in behaviors def ConvertToJavaListRandom(l, minNum, maxNum): int_num = PythonUtilities._py_getRandomNumber("UNIFORM", [0.0, 1.0]) len = maxNum - minNum @@ -105,6 +128,7 @@ def ConvertToJavaListRandom(l, minNum, maxNum): return al +# convenience method to conver a python list to a java list def ConvertToJavaList(l): al = ArrayList() for o in l: @@ -112,6 +136,7 @@ def ConvertToJavaList(l): return al +# convenience method to convert a java list to a python list def ConvertJavaToList(l): al = [] for i in range(l.size()): diff --git a/scripts/jump_start.py b/scripts/jump_start.py index 7cda8dedb951f039b790307f9afefec86fdf0c47..ff1c72410c1f3dfde3bb94ec69e23143f40e0d72 100644 --- a/scripts/jump_start.py +++ b/scripts/jump_start.py @@ -15,37 +15,62 @@ import mtry.cxxi.model.MtryLog.LogManager as LogManager print info.getMyAssignedName(),": JUMP START!" print state.getCurrentCommander(), ": CMDR" +# initialize all the entities HTN systems GoalContainer.initAllEntities() +# create some entity specific loggers LogManager.addSpecificEntityLog("Entity_3") LogManager.addSpecificEntityLog("RFC") +# create the situational awareness tracker (used for managing observations) borg.saTracker = SATracker() borg.saTracker.register(info.getMyAssignedName()) printMessage("SA Inited = "+str(borg.saTracker.retrieveData(info.getMyAssignedName(), "inited")), True) +# create a global parameter to make adding trees easier to change than using the path in trees borg.goalPath = "HTN/Trees/" -entityName = "RFC" ################################################################################################################################################################# # Scenario Parameters ################################################################################################################################################################# +# will the entities move to attack positions at the end of training? borg.isAttackRun = True +# red training positions borg.redDestinations=["TRAINING01", "TRAINING02", "TRAINING03", "TRAINING04", "TRAINING05", "TRAINING06", "TRAINING07", "TRAINING08", "TRAINING09", "TRAINING10", "TRAINING11", "TRAINING12", ] +# red attack positions borg.redAttackDestinations=["ATTACK01", "ATTACK02", "ATTACK03", "ATTACK04", "ATTACK05", "ATTACK06", "ATTACK07", "ATTACK08", "ATTACK09", "ATTACK10", "ATTACK11", "ATTACK12", ] - +# number of setups to perform at each location +# the time at each location equals the number of setups * the time each setup takes +# since that time is random you can't set a fixed time at each location, just a min +# time borg.params_redNumSetups = 1 +# minimum setup time borg.params_redSetupTimeMin = 10 +# amount of random time added to min time borg.params_redSetupTimeVar = 10 +# used to for testing, these are normally all true +# but if you want to just run a single convoy or specific +# convoys you can turn them on and off here. +# Note that even if they are turned off here though, if the +# isAttackRun is true the ALL convoys that are at base will +# be sent to attack positions at the end of a scenario +# regardless of this flag borg.params_activateConvoyOne = True borg.params_activateConvoyTwo = False borg.params_activateConvoyThree = False +# use a background traffic pattern used to add confusion about +# what groups of vehicles are actually convoys. Usually left off +# but you can turn them on here borg.params_useFakeConvoys = False +# use random background traffic borg.params_useRandomMovers = False +# this lets you set the number of destinations to use +# if 0 it will be determined randomly how many to use +# between 1 and 3 borg.params_overrideNumDests = 2 # ignored if 0 ################################################################################################################################################################# # @@ -55,6 +80,7 @@ borg.params_overrideNumDests = 2 # ignored if 0 # 0.5 maps to a 50% chance of attack mode being true borg.attackMode = GetRandomChance(0.5) +# list of random background movers randomMoveVeh = ["Entity_303", "Entity_304", "Entity_305", "Entity_306", "Entity_307", "Entity_308", "Entity_309", "Entity_310", "Entity_311", "Entity_312", "Entity_313", "Entity_314", "Entity_315", "Entity_316", "Entity_317", @@ -78,7 +104,7 @@ fakeConvoy2 = ["Entity_363", "Entity_364", "Entity_365", "Entity_366", "Entity_3 # RFC UtilityFuncsExp.addGoal( - entityName, + "RFC", 0.5, borg.goalPath + "Red/RedForceCoordinator.xml", [],