Commit 41657e3a authored by Ryosuke Suzuki's avatar Ryosuke Suzuki
Browse files

Merge branch 'center_suzuki' into 'develop'

Center suzuki

See merge request !1
parents f6734e74 088d09de
No preview for this file type
......@@ -30,3 +30,5 @@ bin
# Project
precomp_data
test-results
.DS_Store
\ No newline at end of file
#!/bin/sh
./gradlew clean
#!/bin/sh
cd `dirname $0`
rm -rf build
mkdir build
chmod +x gradlew
./gradlew build
## DefaultTacticsAmbulanceTeam
DefaultTacticsAmbulanceTeam.HumanDetector : sample_team.module.complex.SampleHumanDetector
DefaultTacticsAmbulanceTeam.Search : sample_team.module.complex.SampleSearch
DefaultTacticsAmbulanceTeam.HumanDetector : autumn_2023.module.complex.CentralizedControlATHumanDetector
DefaultTacticsAmbulanceTeam.Search : autumn_2023.module.complex.SampleSearch
DefaultTacticsAmbulanceTeam.ExtActionTransport : adf.impl.extaction.DefaultExtActionTransport
DefaultTacticsAmbulanceTeam.ExtActionMove : adf.impl.extaction.DefaultExtActionMove
DefaultTacticsAmbulanceTeam.CommandExecutorAmbulance : adf.impl.centralized.DefaultCommandExecutorAmbulance
DefaultTacticsAmbulanceTeam.CommandExecutorScout : adf.impl.centralized.DefaultCommandExecutorScout
## DefaultTacticsFireBrigade
DefaultTacticsFireBrigade.HumanDetector : sample_team.module.complex.SampleHumanDetector
DefaultTacticsFireBrigade.Search : sample_team.module.complex.SampleSearch
DefaultTacticsFireBrigade.ExtActionFireRescue : adf.impl.extaction.DefaultExtActionFireRescue
DefaultTacticsFireBrigade.HumanDetector : autumn_2023.module.complex.CentralizedControlFBHumanDetector
DefaultTacticsFireBrigade.Search : autumn_2023.module.complex.SampleSearch
DefaultTacticsFireBrigade.ExtActionFireRescue : autumn_2023.extaction.ComplimentTacticsExtActionFireRescue
DefaultTacticsFireBrigade.ExtActionMove : adf.impl.extaction.DefaultExtActionMove
DefaultTacticsFireBrigade.CommandExecutorFire : adf.impl.centralized.DefaultCommandExecutorFire
DefaultTacticsFireBrigade.CommandExecutorFire : autumn_2023.centralized.CentralizedControlCommandExecutorFire
DefaultTacticsFireBrigade.CommandExecutorScout : adf.impl.centralized.DefaultCommandExecutorScout
## DefaultTacticsPoliceForce
......@@ -27,8 +27,8 @@ DefaultTacticsAmbulanceCentre.TargetAllocator : sample_team.module.complex.Sampl
DefaultTacticsAmbulanceCentre.CommandPicker : adf.impl.centralized.DefaultCommandPickerAmbulance
## DefaultTacticsFireStation
DefaultTacticsFireStation.TargetAllocator : sample_team.module.complex.SampleFireTargetAllocator
DefaultTacticsFireStation.CommandPicker : adf.impl.centralized.DefaultCommandPickerFire
DefaultTacticsFireStation.CommandPicker : autumn_2023.centralized.CentralizedControlCommandPickerFire
TacticsFireStation.TargetAllocator : autumn_2023.module.complex.CentralizedControlFBAllocator
## DefaultTacticsPoliceOffice
DefaultTacticsPoliceOffice.TargetAllocator : sample_team.module.complex.SamplePoliceTargetAllocator
......@@ -75,8 +75,8 @@ DefaultCommandExecutorAmbulance.ExtActionMove : adf.impl.extaction.DefaultExtAct
## DefaultCommandExecutorFire
DefaultCommandExecutorFire.PathPlanning : adf.impl.module.algorithm.DijkstraPathPlanning
DefaultCommandExecutorFire.EtxActionFireRescue : adf.impl.extaction.DefaultExtActionFireRescue
DefaultCommandExecutorFire.EtxActionFireFighting : adf.impl.extaction.DefaultExtActionFireFighting
DefaultCommandExecutorFire.ExtActionFireRescue : autumn_2023.extaction.ComplimentTacticsExtActionFireRescue
DefaultCommandExecutorFire.ExtActionFireFighting : adf.impl.extaction.DefaultExtActionFireFighting
DefaultCommandExecutorFire.ExtActionMove : adf.impl.extaction.DefaultExtActionMove
## DefaultCommandExecutorPolice
......@@ -92,10 +92,10 @@ DefaultCommandExecutorScoutPolice.PathPlanning : adf.impl.module.algorithm.Dijks
DefaultCommandExecutorScoutPolice.ExtActionClear : adf.impl.extaction.DefaultExtActionClear
## MessageManager
MessageManager.PlatoonChannelSubscriber : adf.impl.module.comm.DefaultChannelSubscriber
MessageManager.CenterChannelSubscriber : adf.impl.module.comm.DefaultChannelSubscriber
MessageManager.PlatoonMessageCoordinator : adf.impl.module.comm.DefaultMessageCoordinator
MessageManager.CenterMessageCoordinator : adf.impl.module.comm.DefaultMessageCoordinator
MessageManager.PlatoonChannelSubscriber : autumn_2023.module.comm.CentralizedControlChannelSubscriber
MessageManager.CenterChannelSubscriber : autumn_2023.module.comm.CentralizedControlChannelSubscriber
MessageManager.PlatoonMessageCoordinator : autumn_2023.module.comm.CentralizedControlMessageCoordinator
MessageManager.CenterMessageCoordinator : autumn_2023.module.comm.CentralizedControlMessageCoordinator
## VisualDebug
VisualDebug : true
\ No newline at end of file
No preview for this file type
#!/bin/sh
LOADER="adf.impl.DefaultLoader"
PARAMS=$*
cd `dirname $0`
if [ ! -z "$1" ]; then
./gradlew launch --args="${LOADER} ${PARAMS} -pre 1"
else
echo "Options:"
echo "-tn Team name"
echo "-t [FB],[FS],[PF],[PO],[AT],[AC] Number of agents"
echo "-fb [FB] Number of FireBrigade"
echo "-fs [FS] Number of FireStation"
echo "-pf [PF] Number of PoliceForce"
echo "-po [PO] Number of PoliceOffice"
echo "-at [AT] Number of AmbulanceTeam"
echo "-ac [AC] Number of AmbulanceCentre"
echo "-s [HOST]:[PORT] RCRS server host and port"
echo "-h [HOST] RCRS server host (port:27931)"
echo "-pre [0|1] Precompute flag"
echo "-d [0|1] Debug flag"
echo "-dev [0|1] Development mode"
echo "-mc [FILE] ModuleConfig file name"
echo "-md [JSON] ModuleConfig JSON"
echo "-df [FILE] DevelopData JSON file"
echo "-dd [JSON] DevelopData JSON"
echo "-all [alias] -t -1,-1,-1,-1,-1,-1"
echo "-allp [alias] -t 1,0,1,0,1,0,"
echo "-local [alias] -h localhost"
echo "-precompute [alias] -pre 1"
echo "-debug [alias] -d 1"
echo "-develop [alias] -dev 1"
fi
package autumn_2023.centralized;
import static rescuecore2.standard.entities.StandardEntityURN.AMBULANCE_TEAM;
import static rescuecore2.standard.entities.StandardEntityURN.CIVILIAN;
import static rescuecore2.standard.entities.StandardEntityURN.REFUGE;
import adf.core.agent.action.Action;
import adf.core.agent.action.common.ActionMove;
import adf.core.agent.action.common.ActionRest;
import adf.core.agent.communication.MessageManager;
import adf.core.agent.communication.standard.bundle.centralized.CommandAmbulance;
import adf.core.agent.communication.standard.bundle.centralized.CommandFire;
import adf.core.agent.communication.standard.bundle.centralized.MessageReport;
import adf.core.agent.develop.DevelopData;
import adf.core.agent.info.AgentInfo;
......@@ -25,60 +26,67 @@ import rescuecore2.standard.entities.Human;
import rescuecore2.standard.entities.StandardEntity;
import rescuecore2.worldmodel.EntityID;
public class HungarianCommandExecutorAmbulance
extends CommandExecutor<CommandAmbulance> {
public class CentralizedControlCommandExecutorFire extends CommandExecutor<CommandFire> {
private static final int ACTION_UNKNOWN = -1;
private static final int ACTION_REST = CommandAmbulance.ACTION_REST;
private static final int ACTION_MOVE = CommandAmbulance.ACTION_MOVE;
private static final int ACTION_RESCUE = CommandAmbulance.ACTION_RESCUE;
private static final int ACTION_LOAD = CommandAmbulance.ACTION_LOAD;
private static final int ACTION_UNLOAD = CommandAmbulance.ACTION_UNLOAD;
private static final int ACTION_AUTONOMY = CommandAmbulance.ACTION_AUTONOMY;
private static final int ACTION_REST = CommandFire.ACTION_REST;
private static final int ACTION_MOVE = CommandFire.ACTION_MOVE;
private static final int ACTION_RESCUE = CommandFire.ACTION_RESCUE;
private static final int ACTION_AUTONOMY = CommandFire.ACTION_AUTONOMY;
private PathPlanning pathPlanning;
private ExtAction actionTransport;
private ExtAction actionFireRescue;
private ExtAction actionExtMove;
private int commandType;
private EntityID target;
private EntityID commanderID;
public HungarianCommandExecutorAmbulance(AgentInfo ai, WorldInfo wi, ScenarioInfo si, ModuleManager moduleManager, DevelopData developData) {
private boolean commandCompleted;
public CentralizedControlCommandExecutorFire(AgentInfo ai, WorldInfo wi, ScenarioInfo si, ModuleManager moduleManager, DevelopData developData) {
super(ai, wi, si, moduleManager, developData);
this.commandType = ACTION_UNKNOWN;
this.target = null;
this.commanderID = null;
switch (scenarioInfo.getMode()) {
case PRECOMPUTATION_PHASE:
case PRECOMPUTED:
case NON_PRECOMPUTE:
this.pathPlanning = moduleManager.getModule(
"DefaultCommandExecutorAmbulance.PathPlanning",
"DefaultCommandExecutorFire.PathPlanning",
"adf.impl.module.algorithm.DijkstraPathPlanning");
this.actionTransport = moduleManager.getExtAction(
"DefaultCommandExecutorAmbulance.ExtActionTransport",
"adf.impl.extaction.DefaultExtActionTransport");
this.actionFireRescue = moduleManager.getExtAction(
"DefaultCommandExecutorFire.ExtActionFireRescue",
"adf.impl.extaction.DefaultExtActionFireRescue");
this.actionExtMove = moduleManager.getExtAction(
"DefaultCommandExecutorAmbulance.ExActionMove",
"DefaultCommandExecutorFire.ExtActionMove",
"adf.impl.extaction.DefaultExtActionMove");
break;
}
}
/**
* 受信した司令を入力するためのメソッド
* @param command 受信した司令
*/
@Override
public CommandExecutor setCommand(CommandAmbulance command) {
public CommandExecutor setCommand(CommandFire command) {
EntityID agentID = this.agentInfo.getID();
if (command.isToIDDefined() && Objects.requireNonNull(command.getToID())
.getValue() == agentID.getValue()) {
this.commandType = command.getAction();
this.target = command.getTargetID();
this.commanderID = command.getSenderID();
if(!this.commandCompleted) return this;
if (command.isToIDDefined() && Objects.requireNonNull(command.getToID()).getValue() == agentID.getValue()) {
this.commandType = command.getAction();// 司令で出された行動内容
this.target = command.getTargetID();// タスクとなる対象のID
this.commanderID = command.getSenderID();// 司令を出した司令所のID
}
return this;
}
/**
* 現在実行している司令が完了しているかを判定する
* 完了しているなら,消防司令所へ救助完了の報告を送る
*/
@Override
public CommandExecutor updateInfo(MessageManager messageManager) {
super.updateInfo(messageManager);
......@@ -86,23 +94,19 @@ public class HungarianCommandExecutorAmbulance
return this;
}
this.pathPlanning.updateInfo(messageManager);
this.actionTransport.updateInfo(messageManager);
this.actionFireRescue.updateInfo(messageManager);
this.actionExtMove.updateInfo(messageManager);
if (this.isCommandCompleted()) {
this.commandCompleted = this.isCommandCompleted(this.commandType);
if (this.commandCompleted) {
if (this.commandType != ACTION_UNKNOWN) {
messageManager
.addMessage(new MessageReport(true, true, false, this.commanderID));
if (this.commandType == ACTION_LOAD) {
this.commandType = ACTION_UNLOAD;
this.target = null;
} else {
messageManager.addMessage(new MessageReport(true, true, false, this.target));
this.commandType = ACTION_UNKNOWN;
this.target = null;
this.commanderID = null;
}
}
}
return this;
}
......@@ -114,7 +118,7 @@ public class HungarianCommandExecutorAmbulance
return this;
}
this.pathPlanning.precompute(precomputeData);
this.actionTransport.precompute(precomputeData);
this.actionFireRescue.precompute(precomputeData);
this.actionExtMove.precompute(precomputeData);
return this;
}
......@@ -127,7 +131,7 @@ public class HungarianCommandExecutorAmbulance
return this;
}
this.pathPlanning.resume(precomputeData);
this.actionTransport.resume(precomputeData);
this.actionFireRescue.resume(precomputeData);
this.actionExtMove.resume(precomputeData);
return this;
}
......@@ -140,12 +144,17 @@ public class HungarianCommandExecutorAmbulance
return this;
}
this.pathPlanning.preparate();
this.actionTransport.preparate();
this.actionFireRescue.preparate();
this.actionExtMove.preparate();
return this;
}
/**
* 受け取った司令を元に行動を決定・実行するためのメソッド
*
* 司令で出された行動内容によって救助活動を決定する
* ※実装では司令で出される行動内容はACTION_AUTONOMYになっている
*/
@Override
public CommandExecutor calc() {
this.result = null;
......@@ -153,8 +162,7 @@ public class HungarianCommandExecutorAmbulance
case ACTION_REST:
EntityID position = this.agentInfo.getPosition();
if (this.target == null) {
Collection<
EntityID> refuges = this.worldInfo.getEntityIDsOfType(REFUGE);
Collection<EntityID> refuges = this.worldInfo.getEntityIDsOfType(REFUGE);
if (refuges.contains(position)) {
this.result = new ActionRest();
} else {
......@@ -181,26 +189,12 @@ public class HungarianCommandExecutorAmbulance
return this;
case ACTION_MOVE:
if (this.target != null) {
this.result = this.actionExtMove.setTarget(this.target).calc()
.getAction();
this.result = this.actionExtMove.setTarget(this.target).calc().getAction();
}
return this;
case ACTION_RESCUE:
if (this.target != null) {
this.result = this.actionTransport.setTarget(this.target).calc()
.getAction();
}
return this;
case ACTION_LOAD:
if (this.target != null) {
this.result = this.actionTransport.setTarget(this.target).calc()
.getAction();
}
return this;
case ACTION_UNLOAD:
if (this.target != null) {
this.result = this.actionTransport.setTarget(this.target).calc()
.getAction();
this.result = this.actionFireRescue.setTarget(this.target).calc().getAction();
}
return this;
case ACTION_AUTONOMY:
......@@ -209,25 +203,23 @@ public class HungarianCommandExecutorAmbulance
}
StandardEntity targetEntity = this.worldInfo.getEntity(this.target);
if (targetEntity instanceof Area) {
if (this.agentInfo.someoneOnBoard() == null) {
this.result = this.actionExtMove.setTarget(this.target).calc()
.getAction();
} else {
this.result = this.actionTransport.setTarget(this.target).calc()
.getAction();
}
this.result = this.actionExtMove.setTarget(this.target).calc().getAction();
} else if (targetEntity instanceof Human) {
this.result = this.actionTransport.setTarget(this.target).calc()
.getAction();
this.result = this.actionFireRescue.setTarget(this.target).calc().getAction();
}
}
return this;
}
private boolean isCommandCompleted() {
/**
* 司令が完了したかを判定するメソッド
*
* @param commandType 司令の種類
* @return true : 完了 false : 実行中
*/
private boolean isCommandCompleted(int commandType) {
Human agent = (Human) this.agentInfo.me();
switch (this.commandType) {
switch (commandType) {
case ACTION_REST:
if (this.target == null) {
return (agent.getDamage() == 0);
......@@ -246,61 +238,19 @@ public class HungarianCommandExecutorAmbulance
if (this.target == null) {
return true;
}
Human human = (Human) Objects
.requireNonNull(this.worldInfo.getEntity(this.target));
Human human = (Human) Objects.requireNonNull(this.worldInfo.getEntity(this.target));
return human.isBuriednessDefined() && human.getBuriedness() == 0
|| (human.isHPDefined() && human.getHP() == 0);
case ACTION_LOAD:
if (this.target == null) {
return true;
}
Human human1 = (Human) Objects
.requireNonNull(this.worldInfo.getEntity(this.target));
if ((human1.isHPDefined() && human1.getHP() == 0)) {
return true;
}
if (human1.getStandardURN() != CIVILIAN) {
this.commandType = ACTION_RESCUE;
return this.isCommandCompleted();
}
if (human1.isPositionDefined()) {
EntityID position = human1.getPosition();
if (this.worldInfo.getEntityIDsOfType(AMBULANCE_TEAM)
.contains(position)) {
return true;
} else if (this.worldInfo.getEntity(position)
.getStandardURN() == REFUGE) {
return true;
}
}
return false;
case ACTION_UNLOAD:
if (this.target != null) {
StandardEntity entity = this.worldInfo.getEntity(this.target);
if (entity != null && entity instanceof Area) {
if (this.target.getValue() != this.agentInfo.getPosition()
.getValue()) {
return false;
}
}
}
return (this.agentInfo.someoneOnBoard() == null);
case ACTION_AUTONOMY:
if (this.target != null) {
StandardEntity targetEntity = this.worldInfo.getEntity(this.target);
if (targetEntity instanceof Area) {
this.commandType = this.agentInfo.someoneOnBoard() == null
? ACTION_MOVE
: ACTION_UNLOAD;
return this.isCommandCompleted();
commandType = ACTION_MOVE;
return this.isCommandCompleted(commandType);
} else if (targetEntity instanceof Human) {
Human h = (Human) targetEntity;
if ((h.isHPDefined() && h.getHP() == 0)) {
return true;
}
this.commandType = h.getStandardURN() == CIVILIAN ? ACTION_LOAD
: ACTION_RESCUE;
return this.isCommandCompleted();
commandType = ACTION_RESCUE;
return this.isCommandCompleted(commandType);
}
}
return true;
......
package autumn_2023.centralized;
import adf.core.agent.communication.standard.bundle.centralized.CommandFire;
import adf.core.agent.communication.standard.bundle.centralized.CommandScout;
import adf.core.agent.develop.DevelopData;
import adf.core.agent.info.AgentInfo;
import adf.core.agent.info.ScenarioInfo;
import adf.core.agent.info.WorldInfo;
import adf.core.agent.module.ModuleManager;
import adf.core.component.centralized.CommandPicker;
import adf.core.component.communication.CommunicationMessage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import rescuecore2.standard.entities.Area;
import rescuecore2.standard.entities.Human;
import rescuecore2.standard.entities.StandardEntity;
import rescuecore2.standard.entities.StandardEntityURN;
import rescuecore2.worldmodel.EntityID;
public class CentralizedControlCommandPickerFire extends CommandPicker {
private int scoutDistance;
private Collection<CommunicationMessage> messages;
private Map<EntityID, EntityID> allocationData;
public CentralizedControlCommandPickerFire(AgentInfo ai, WorldInfo wi, ScenarioInfo si, ModuleManager moduleManager, DevelopData developData) {
super(ai, wi, si, moduleManager, developData);
this.messages = new ArrayList<>();
this.allocationData = null;
this.scoutDistance = developData.getInteger(
"adf.impl.centralized.DefaultCommandPickerFire.scoutDistance", 40000);
}
/**
* TargetAllocatorの計算結果を入力するためのメソッド
*
* @param allocationData TargetAllocatorのgetResultメソッドの戻り値
*/
@Override
public CommandPicker
setAllocatorResult(Map<EntityID, EntityID> allocationData) {
this.allocationData = allocationData;
return this;
}
/**
* 司令を生成・リスト化するためのメソッド
* 司令はTargetAllocatorから受け取った司令内容をもとに生成される
*/
@Override
public CommandPicker calc() {
this.messages.clear();
if (this.allocationData == null) {
return this;
}
for (EntityID agentID : this.allocationData.keySet()) {
StandardEntity agent = this.worldInfo.getEntity(agentID);
if (agent != null
&& agent.getStandardURN() == StandardEntityURN.FIRE_BRIGADE) {
StandardEntity target = this.worldInfo.getEntity(this.allocationData.get(agentID));
if (target != null) {
if (target instanceof Human) {
CommandFire command = new CommandFire(true, agentID, target.getID(), CommandFire.ACTION_AUTONOMY);
this.messages.add(command);
}
}
}
}
return this;
}
/**
* calcメソッドで生成した司令リストを取得するためのメソッド
* @return 司令リスト
*/
@Override
public Collection<CommunicationMessage> getResult() {
return this.messages;
}
}
\ No newline at end of file
package autumn_2023.extaction;
import static rescuecore2.standard.entities.StandardEntityURN.BLOCKADE;
import adf.core.agent.action.Action;
import adf.core.agent.action.ambulance.ActionRescue;
import adf.core.agent.action.common.ActionMove;
import adf.core.agent.communication.MessageManager;
import adf.core.agent.communication.standard.bundle.information.MessageFireBrigade;
import adf.core.agent.develop.DevelopData;
import adf.core.agent.info.AgentInfo;
import adf.core.agent.info.ScenarioInfo;
import adf.core.agent.info.WorldInfo;
import adf.core.agent.module.ModuleManager;
import adf.core.agent.precompute.PrecomputeData;
import adf.core.component.extaction.ExtAction;
import adf.core.component.module.algorithm.PathPlanning;
import java.util.ArrayList;
import java.util.List;
import rescuecore2.config.NoSuchConfigOptionException;
import rescuecore2.standard.entities.Area;
import rescuecore2.standard.entities.Blockade;
import rescuecore2.standard.entities.FireBrigade;
import rescuecore2.standard.entities.Human;
import rescuecore2.standard.entities.StandardEntity;
import rescuecore2.worldmodel.EntityID;
// ADFのDefaultTacticsFireBrigadeの修正用プログラム 無視してよい
public class ComplimentTacticsExtActionFireRescue extends ExtAction {
private MessageManager mm;
private PathPlanning pathPlanning;
private int thresholdRest;
private int kernelTime;
private EntityID target;
public ComplimentTacticsExtActionFireRescue(AgentInfo agentInfo, WorldInfo worldInfo, ScenarioInfo scenarioInfo, ModuleManager moduleManager, DevelopData developData) {
super(agentInfo, worldInfo, scenarioInfo, moduleManager, developData);
this.target = null;
this.thresholdRest = developData
.getInteger("adf.impl.extaction.DefaultExtActionFireRescue.rest", 100);
switch (scenarioInfo.getMode()) {
case PRECOMPUTATION_PHASE:
case PRECOMPUTED:
case NON_PRECOMPUTE:
this.pathPlanning = moduleManager.getModule(
"DefaultExtActionFireRescue.PathPlanning",
"adf.impl.module.algorithm.DijkstraPathPlanning");
break;
}
}
public ExtAction precompute(PrecomputeData precomputeData) {
super.precompute(precomputeData);
if (this.getCountPrecompute() >= 2) {
return this;
}
this.pathPlanning.precompute(precomputeData);
try {
this.kernelTime = this.scenarioInfo.getKernelTimesteps();
} catch (NoSuchConfigOptionException e) {
this.kernelTime = -1;
}
return this;
}
public ExtAction resume(PrecomputeData precomputeData) {
super.resume(precomputeData);
if (this.getCountResume() >= 2) {
return this;
}
this.pathPlanning.resume(precomputeData);
try {
this.kernelTime = this.scenarioInfo.getKernelTimesteps();
} catch (NoSuchConfigOptionException e) {
this.kernelTime = -1;
}
return this;
}
public ExtAction preparate() {
super.preparate();
if (this.getCountPreparate() >= 2) {
return this;
}
this.pathPlanning.preparate();
try {
this.kernelTime = this.scenarioInfo.getKernelTimesteps();
} catch (NoSuchConfigOptionException e) {
this.kernelTime = -1;
}
return this;
}
public ExtAction updateInfo(MessageManager messageManager) {
super.updateInfo(messageManager);
if (this.getCountUpdateInfo() >= 2) {
return this;
}
this.mm = messageManager;
this.pathPlanning.updateInfo(messageManager);
return this;
}
@Override
public ExtAction setTarget(EntityID target) {
this.target = null;
if (target != null) {
StandardEntity entity = this.worldInfo.getEntity(target);
if (entity instanceof Human || entity instanceof Area) {
this.target = target;
return this;
}
}
return this;
}
@Override
public ExtAction calc() {
this.result = null;
FireBrigade agent = (FireBrigade) this.agentInfo.me();
if (this.needRest(agent)) {
EntityID areaID = this.convertArea(this.target);
ArrayList<EntityID> targets = new ArrayList<>();
if (areaID != null) {
targets.add(areaID);
}
}
if (this.target != null) {
this.result = this.calcRescue(agent, this.pathPlanning, this.target);
}
if(this.result != null){
Class<? extends Action> actionClass = this.result.getClass();
if (actionClass == ActionRescue.class) {
this.mm.addMessage(new MessageFireBrigade(true, agent, MessageFireBrigade.ACTION_RESCUE, this.target));
}
}
return this;
}
private Action calcRescue(FireBrigade agent, PathPlanning pathPlanning,
EntityID targetID) {
StandardEntity targetEntity = this.worldInfo.getEntity(targetID);
if (targetEntity == null) {
return null;
}
EntityID agentPosition = agent.getPosition();
if (targetEntity instanceof Human) {
Human human = (Human) targetEntity;
if (!human.isPositionDefined()) {
return null;
}
if (human.isHPDefined() && human.getHP() == 0) {
return null;
}
EntityID targetPosition = human.getPosition();
if (agentPosition.getValue() == targetPosition.getValue()) {
if (human.isBuriednessDefined() && human.getBuriedness() > 0) {
return new ActionRescue(human);
}
} else {
List<EntityID> path = pathPlanning.getResult(agentPosition,
targetPosition);
if (path != null && path.size() > 0) {
return new ActionMove(path);
}
}
return null;
}
if (targetEntity.getStandardURN() == BLOCKADE) {
Blockade blockade = (Blockade) targetEntity;
if (blockade.isPositionDefined()) {
targetEntity = this.worldInfo.getEntity(blockade.getPosition());
}
}
if (targetEntity instanceof Area) {
List<EntityID> path = pathPlanning.getResult(agentPosition,
targetEntity.getID());
if (path != null && path.size() > 0) {
return new ActionMove(path);
}
}
return null;
}
private boolean needRest(Human agent) {
int hp = agent.getHP();
int damage = agent.getDamage();
if (hp == 0 || damage == 0) {
return false;
}
int activeTime = (hp / damage) + ((hp % damage) != 0 ? 1 : 0);
if (this.kernelTime == -1) {
try {
this.kernelTime = this.scenarioInfo.getKernelTimesteps();
} catch (NoSuchConfigOptionException e) {
this.kernelTime = -1;
}
}
return damage >= this.thresholdRest
|| (activeTime + this.agentInfo.getTime()) < this.kernelTime;
}
private EntityID convertArea(EntityID targetID) {
StandardEntity entity = this.worldInfo.getEntity(targetID);
if (entity == null) {
return null;
}
if (entity instanceof Human) {
Human human = (Human) entity;
if (human.isPositionDefined()) {
EntityID position = human.getPosition();
if (this.worldInfo.getEntity(position) instanceof Area) {
return position;
}
}
} else if (entity instanceof Area) {
return targetID;
} else if (entity.getStandardURN() == BLOCKADE) {
Blockade blockade = (Blockade) entity;
if (blockade.isPositionDefined()) {
return blockade.getPosition();
}
}
return null;
}
}
\ No newline at end of file
package autumn_2023.module.comm;
import adf.core.agent.communication.MessageManager;
import adf.core.agent.info.AgentInfo;
import adf.core.agent.info.ScenarioInfo;
import adf.core.agent.info.WorldInfo;
import adf.core.component.communication.ChannelSubscriber;
import rescuecore2.standard.entities.StandardEntityURN;
public class CentralizedControlChannelSubscriber extends ChannelSubscriber {
@Override
public void subscribe(AgentInfo agentInfo, WorldInfo worldInfo,
ScenarioInfo scenarioInfo, MessageManager messageManager) {
// subscribe only once at the beginning
if (agentInfo.getTime() == 1) {
int numChannels = scenarioInfo.getCommsChannelsCount() - 1; // 0th channel
// is the
// voice
// channel
int maxChannelCount = 0;
boolean isPlatoon = isPlatoonAgent(agentInfo, worldInfo);
if (isPlatoon) {
maxChannelCount = scenarioInfo.getCommsChannelsMaxPlatoon();
} else {
maxChannelCount = scenarioInfo.getCommsChannelsMaxOffice();
}
StandardEntityURN agentType = getAgentType(agentInfo, worldInfo);
int[] channels = new int[maxChannelCount];
for (int i = 0; i < maxChannelCount; i++) {
channels[i] = getChannelNumber(agentType, i, numChannels);
}
messageManager.subscribeToChannels(channels);
}
}
protected boolean isPlatoonAgent(AgentInfo agentInfo, WorldInfo worldInfo) {
StandardEntityURN agentType = getAgentType(agentInfo, worldInfo);
if (agentType == StandardEntityURN.FIRE_BRIGADE
|| agentType == StandardEntityURN.POLICE_FORCE
|| agentType == StandardEntityURN.AMBULANCE_TEAM) {
return true;
}
return false;
}
protected StandardEntityURN getAgentType(AgentInfo agentInfo,
WorldInfo worldInfo) {
StandardEntityURN agentType = worldInfo.getEntity(agentInfo.getID())
.getStandardURN();
return agentType;
}
public static int getChannelNumber(StandardEntityURN agentType,
int channelIndex, int numChannels) {
int agentIndex = 0;
if (agentType == StandardEntityURN.FIRE_BRIGADE
|| agentType == StandardEntityURN.FIRE_STATION) {
agentIndex = 1;
} else if (agentType == StandardEntityURN.POLICE_FORCE
|| agentType == StandardEntityURN.POLICE_OFFICE) {
agentIndex = 2;
} else if (agentType == StandardEntityURN.AMBULANCE_TEAM
|| agentType == StandardEntityURN.AMBULANCE_CENTRE) {
agentIndex = 3;
}
int index = (3 * channelIndex) + agentIndex;
if ((index % numChannels) == 0) {
index = numChannels;
} else {
index = index % numChannels;
}
return index;
}
public static void main(String[] args) {
int numChannels = 6;
int maxChannels = 2;
for (int i = 0; i < maxChannels; i++) {
System.out.println("FIREBRIGADE-" + i + ":"
+ getChannelNumber(StandardEntityURN.FIRE_BRIGADE, i, numChannels));
}
for (int i = 0; i < maxChannels; i++) {
System.out.println("POLICE-" + i + ":"
+ getChannelNumber(StandardEntityURN.POLICE_OFFICE, i, numChannels));
}
for (int i = 0; i < maxChannels; i++) {
System.out.println("AMB-" + i + ":" + getChannelNumber(
StandardEntityURN.AMBULANCE_CENTRE, i, numChannels));
}
}
}
\ No newline at end of file
package autumn_2023.module.comm;
import adf.core.agent.communication.MessageManager;
import adf.core.agent.communication.standard.bundle.StandardMessage;
import adf.core.agent.communication.standard.bundle.StandardMessagePriority;
import adf.core.agent.communication.standard.bundle.centralized.CommandAmbulance;
import adf.core.agent.communication.standard.bundle.centralized.CommandFire;
import adf.core.agent.communication.standard.bundle.centralized.CommandPolice;
import adf.core.agent.communication.standard.bundle.centralized.CommandScout;
import adf.core.agent.communication.standard.bundle.centralized.MessageReport;
import adf.core.agent.communication.standard.bundle.information.MessageAmbulanceTeam;
import adf.core.agent.communication.standard.bundle.information.MessageBuilding;
import adf.core.agent.communication.standard.bundle.information.MessageCivilian;
import adf.core.agent.communication.standard.bundle.information.MessageFireBrigade;
import adf.core.agent.communication.standard.bundle.information.MessagePoliceForce;
import adf.core.agent.communication.standard.bundle.information.MessageRoad;
import adf.core.agent.info.AgentInfo;
import adf.core.agent.info.ScenarioInfo;
import adf.core.agent.info.WorldInfo;
import adf.core.component.communication.CommunicationMessage;
import adf.core.component.communication.MessageCoordinator;
import adf.impl.module.comm.DefaultChannelSubscriber;
import java.util.ArrayList;
import java.util.List;
import rescuecore2.standard.entities.StandardEntityURN;
public class CentralizedControlMessageCoordinator extends MessageCoordinator {
@Override
public void coordinate(AgentInfo agentInfo, WorldInfo worldInfo,
ScenarioInfo scenarioInfo, MessageManager messageManager,
ArrayList<CommunicationMessage> sendMessageList,
List<List<CommunicationMessage>> channelSendMessageList) {
// have different lists for every agent
ArrayList<CommunicationMessage> policeMessages = new ArrayList<>();
ArrayList<CommunicationMessage> ambulanceMessages = new ArrayList<>();
ArrayList<CommunicationMessage> fireBrigadeMessages = new ArrayList<>();
ArrayList<CommunicationMessage> voiceMessages = new ArrayList<>();
StandardEntityURN agentType = getAgentType(agentInfo, worldInfo);
for (CommunicationMessage msg : sendMessageList) {
if (msg instanceof StandardMessage
&& !((StandardMessage) msg).isRadio()) {
voiceMessages.add(msg);
} else {
if (msg instanceof MessageBuilding) {
fireBrigadeMessages.add(msg);
} else if (msg instanceof MessageCivilian) {
fireBrigadeMessages.add(msg);
ambulanceMessages.add(msg);
} else if (msg instanceof MessageRoad) {
fireBrigadeMessages.add(msg);
ambulanceMessages.add(msg);
policeMessages.add(msg);
} else if (msg instanceof CommandAmbulance) {
ambulanceMessages.add(msg);
} else if (msg instanceof CommandFire) {
fireBrigadeMessages.add(msg);
} else if (msg instanceof CommandPolice) {
policeMessages.add(msg);
} else if (msg instanceof CommandScout) {
if (agentType == StandardEntityURN.FIRE_STATION) {
fireBrigadeMessages.add(msg);
} else if (agentType == StandardEntityURN.POLICE_OFFICE) {
policeMessages.add(msg);
} else if (agentType == StandardEntityURN.AMBULANCE_CENTRE) {
ambulanceMessages.add(msg);
}
} else if (msg instanceof MessageReport) {
if (agentType == StandardEntityURN.FIRE_BRIGADE) {
fireBrigadeMessages.add(msg);
} else if (agentType == StandardEntityURN.POLICE_FORCE) {
policeMessages.add(msg);
} else if (agentType == StandardEntityURN.AMBULANCE_TEAM) {
ambulanceMessages.add(msg);
}
} else if (msg instanceof MessageFireBrigade) {
fireBrigadeMessages.add(msg);
ambulanceMessages.add(msg);
policeMessages.add(msg);
} else if (msg instanceof MessagePoliceForce) {
ambulanceMessages.add(msg);
policeMessages.add(msg);
} else if (msg instanceof MessageAmbulanceTeam) {
ambulanceMessages.add(msg);
policeMessages.add(msg);
}
}
}
if (scenarioInfo.getCommsChannelsCount() > 1) {
// send radio messages if there are more than one communication channel
int[] channelSize = new int[scenarioInfo.getCommsChannelsCount() - 1];
setSendMessages(scenarioInfo, StandardEntityURN.POLICE_FORCE, agentInfo,
worldInfo, policeMessages, channelSendMessageList, channelSize);
setSendMessages(scenarioInfo, StandardEntityURN.AMBULANCE_TEAM, agentInfo,
worldInfo, ambulanceMessages, channelSendMessageList, channelSize);
setSendMessages(scenarioInfo, StandardEntityURN.FIRE_BRIGADE, agentInfo,
worldInfo, fireBrigadeMessages, channelSendMessageList, channelSize);
}
ArrayList<StandardMessage> voiceMessageLowList = new ArrayList<>();
ArrayList<StandardMessage> voiceMessageNormalList = new ArrayList<>();
ArrayList<StandardMessage> voiceMessageHighList = new ArrayList<>();
for (CommunicationMessage msg : voiceMessages) {
if (msg instanceof StandardMessage) {
StandardMessage m = (StandardMessage) msg;
switch (m.getSendingPriority()) {
case LOW:
voiceMessageLowList.add(m);
break;
case NORMAL:
voiceMessageNormalList.add(m);
break;
case HIGH:
voiceMessageHighList.add(m);
break;
}
}
}
// set the voice channel messages
channelSendMessageList.get(0).addAll(voiceMessageHighList);
channelSendMessageList.get(0).addAll(voiceMessageNormalList);
channelSendMessageList.get(0).addAll(voiceMessageLowList);
}
protected int[] getChannelsByAgentType(StandardEntityURN agentType,
AgentInfo agentInfo, WorldInfo worldInfo, ScenarioInfo scenarioInfo,
int channelIndex) {
int numChannels = scenarioInfo.getCommsChannelsCount() - 1; // 0th channel
// is the voice
// channel
int maxChannelCount = 0;
boolean isPlatoon = isPlatoonAgent(agentInfo, worldInfo);
if (isPlatoon) {
maxChannelCount = scenarioInfo.getCommsChannelsMaxPlatoon();
} else {
maxChannelCount = scenarioInfo.getCommsChannelsMaxOffice();
}
int[] channels = new int[maxChannelCount];
for (int i = 0; i < maxChannelCount; i++) {
channels[i] = DefaultChannelSubscriber.getChannelNumber(agentType, i,
numChannels);
}
return channels;
}
protected boolean isPlatoonAgent(AgentInfo agentInfo, WorldInfo worldInfo) {
StandardEntityURN agentType = getAgentType(agentInfo, worldInfo);
if (agentType == StandardEntityURN.FIRE_BRIGADE
|| agentType == StandardEntityURN.POLICE_FORCE
|| agentType == StandardEntityURN.AMBULANCE_TEAM) {
return true;
}
return false;
}
protected StandardEntityURN getAgentType(AgentInfo agentInfo,
WorldInfo worldInfo) {
StandardEntityURN agentType = worldInfo.getEntity(agentInfo.getID())
.getStandardURN();
return agentType;
}
protected void setSendMessages(ScenarioInfo scenarioInfo,
StandardEntityURN agentType, AgentInfo agentInfo, WorldInfo worldInfo,
List<CommunicationMessage> messages,
List<List<CommunicationMessage>> channelSendMessageList,
int[] channelSize) {
int channelIndex = 0;
int[] channels = getChannelsByAgentType(agentType, agentInfo, worldInfo,
scenarioInfo, channelIndex);
int channel = channels[channelIndex];
int channelCapacity = scenarioInfo.getCommsChannelBandwidth(channel);
// start from HIGH, NORMAL, to LOW
for (int i = StandardMessagePriority.values().length - 1; i >= 0; i--) {
for (CommunicationMessage msg : messages) {
StandardMessage smsg = (StandardMessage) msg;
if (smsg.getSendingPriority() == StandardMessagePriority.values()[i]) {
channelSize[channel - 1] += smsg.getByteArraySize();
if (channelSize[channel - 1] > channelCapacity) {
channelSize[channel - 1] -= smsg.getByteArraySize();
channelIndex++;
if (channelIndex < channels.length) {
channel = channels[channelIndex];
channelCapacity = scenarioInfo.getCommsChannelBandwidth(channel);
channelSize[channel - 1] += smsg.getByteArraySize();
} else {
// if there is no new channel for that message types, just break
break;
}
}
channelSendMessageList.get(channel).add(smsg);
}
}
}
}
}
\ No newline at end of file
package autumn_2023.module.complex;
import static rescuecore2.standard.entities.StandardEntityURN.AMBULANCE_TEAM;
import static rescuecore2.standard.entities.StandardEntityURN.CIVILIAN;
import static rescuecore2.standard.entities.StandardEntityURN.REFUGE;
import adf.core.agent.action.Action;
import adf.core.agent.communication.MessageManager;
import adf.core.agent.communication.standard.bundle.StandardMessageBundle;
import adf.core.agent.communication.standard.bundle.StandardMessagePriority;
import adf.core.agent.communication.standard.bundle.information.MessageBuilding;
import adf.core.agent.communication.standard.bundle.information.MessageCivilian;
import adf.core.agent.develop.DevelopData;
import adf.core.agent.info.AgentInfo;
import adf.core.agent.info.ScenarioInfo;
import adf.core.agent.info.WorldInfo;
import adf.core.agent.module.ModuleManager;
import adf.core.component.communication.CommunicationMessage;
import adf.core.component.module.algorithm.Clustering;
import adf.core.component.module.complex.HumanDetector;
import adf.core.debug.DefaultLogger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.log4j.Logger;
import rescuecore2.standard.entities.Building;
import rescuecore2.standard.entities.Civilian;
import rescuecore2.standard.entities.Human;
import rescuecore2.standard.entities.StandardEntity;
import rescuecore2.standard.entities.StandardEntityURN;
import rescuecore2.worldmodel.EntityID;
public class CentralizedControlATHumanDetector extends HumanDetector {
private Clustering clustering;
private EntityID result;
private Logger logger;
public CentralizedControlATHumanDetector(AgentInfo ai, WorldInfo wi, ScenarioInfo si, ModuleManager moduleManager, DevelopData developData) {
super(ai, wi, si, moduleManager, developData);
logger = DefaultLogger.getLogger(agentInfo.me());
this.clustering = moduleManager.getModule("SampleHumanDetector.Clustering",
"adf.impl.module.algorithm.KMeansClustering");
registerModule(this.clustering);
}
/**
* 新しく受信したメッセージから情報を取得するためのメソッド
*
* 現在のステップで知覚した埋没市民を送信する
*/
@Override
public HumanDetector updateInfo(MessageManager messageManager) {
logger.debug("Time:" + agentInfo.getTime());
super.updateInfo(messageManager);
Set<EntityID> changes = this.worldInfo.getChanged().getChangedEntities();
for(EntityID id : changes){
StandardEntity entity = this.worldInfo.getEntity(id);
if(!(entity instanceof Civilian)) continue;
Civilian civ = (Civilian) entity;
if(!this.isNeedRescueHuman(civ)){
continue;
}
StandardMessagePriority level = StandardMessagePriority.NORMAL;
MessageCivilian civ_mes = new MessageCivilian(true, level, civ);
messageManager.addMessage(civ_mes,true);
}
return this;
}
/**
* 搬送対象のIDを求めるメソッド
*/
@Override
public HumanDetector calc() {
Human transportHuman = this.agentInfo.someoneOnBoard();
if (transportHuman != null) {
logger.debug("someoneOnBoard:" + transportHuman);
this.result = transportHuman.getID();
return this;
}
if (this.result != null) {
Human target = (Human) this.worldInfo.getEntity(this.result);
if (!isValidHuman(target)) {
logger.debug("Invalid Human:" + target + " ==>reset target");
this.result = null;
}
}
if (this.result == null) {
this.result = calcTarget();
}
return this;
}
private EntityID calcTarget() {
List<Human> rescueTargets = filterRescueTargets(
this.worldInfo.getEntitiesOfType(CIVILIAN));
List<Human> rescueTargetsInCluster = filterInCluster(rescueTargets);
List<Human> targets = rescueTargetsInCluster;
if (targets.isEmpty())
targets = rescueTargets;
logger.debug("Targets:" + targets);
if (!targets.isEmpty()) {
targets.sort(new DistanceSorter(this.worldInfo, this.agentInfo.me()));
Human selected = targets.get(0);
logger.debug("Selected:" + selected);
return selected.getID();
}
return null;
}
/**
* 救助対象IDを返すメソッド
*/
@Override
public EntityID getTarget() {
return this.result;
}
private List<Human>
filterRescueTargets(Collection<? extends StandardEntity> list) {
List<Human> rescueTargets = new ArrayList<>();
for (StandardEntity next : list) {
if (!(next instanceof Human))
continue;
Human h = (Human) next;
if (!isValidHuman(h))
continue;
if (h.getBuriedness() == 0)
continue;
rescueTargets.add(h);
}
return rescueTargets;
}
private List<Human>
filterInCluster(Collection<? extends StandardEntity> entities) {
int clusterIndex = clustering.getClusterIndex(this.agentInfo.getID());
List<Human> filter = new ArrayList<>();
HashSet<StandardEntity> inCluster = new HashSet<>(
clustering.getClusterEntities(clusterIndex));
for (StandardEntity next : entities) {
if (!(next instanceof Human))
continue;
Human h = (Human) next;
if (!h.isPositionDefined())
continue;
StandardEntity position = this.worldInfo.getPosition(h);
if (position == null)
continue;
if (!inCluster.contains(position))
continue;
filter.add(h);
}
return filter;
}
private class DistanceSorter implements Comparator<StandardEntity> {
private StandardEntity reference;
private WorldInfo worldInfo;
DistanceSorter(WorldInfo wi, StandardEntity reference) {
this.reference = reference;
this.worldInfo = wi;
}
public int compare(StandardEntity a, StandardEntity b) {
int d1 = this.worldInfo.getDistance(this.reference, a);
int d2 = this.worldInfo.getDistance(this.reference, b);
return d1 - d2;
}
}
private boolean isValidHuman(StandardEntity entity) {
if (entity == null)
return false;
if (!(entity instanceof Human))
return false;
Human target = (Human) entity;
if (!target.isHPDefined() || target.getHP() == 0)
return false;
if (!target.isPositionDefined())
return false;
if (!target.isDamageDefined() || target.getDamage() == 0)
return false;
if (!target.isBuriednessDefined())
return false;
StandardEntity position = worldInfo.getPosition(target);
if (position == null)
return false;
StandardEntityURN positionURN = position.getStandardURN();
if (positionURN == REFUGE || positionURN == AMBULANCE_TEAM)
return false;
return true;
}
private boolean isNeedRescueHuman(StandardEntity entity){
if (entity == null)
return false;
if (!(entity instanceof Human))
return false;
Human target = (Human) entity;
if (!target.isHPDefined() || target.getHP() == 0)
return false;
if (!target.isPositionDefined())
return false;
if (!target.isBuriednessDefined() || target.getBuriedness() == 0)
return false;
StandardEntity position = worldInfo.getPosition(target);
if (position == null)
return false;
StandardEntityURN positionURN = position.getStandardURN();
if (positionURN == REFUGE || positionURN == AMBULANCE_TEAM)
return false;
return true;
}
}
\ No newline at end of file
package autumn_2023.module.complex;
import autumn_2023.module.algorithm.Hungarian;
import adf.core.agent.communication.MessageManager;
import adf.core.agent.communication.standard.bundle.MessageUtil;
import adf.core.agent.communication.standard.bundle.StandardMessageBundle;
import adf.core.agent.communication.standard.bundle.StandardMessagePriority;
import adf.core.agent.communication.standard.bundle.centralized.MessageReport;
import adf.core.agent.communication.standard.bundle.information.MessageBuilding;
import adf.core.agent.communication.standard.bundle.information.MessageCivilian;
import adf.core.agent.communication.standard.bundle.information.MessageFireBrigade;
import adf.core.agent.develop.DevelopData;
import adf.core.agent.info.AgentInfo;
import adf.core.agent.info.ScenarioInfo;
import adf.core.agent.info.WorldInfo;
import adf.core.agent.module.ModuleManager;
import adf.core.agent.precompute.PrecomputeData;
import adf.core.component.communication.CommunicationMessage;
import adf.core.component.module.complex.FireTargetAllocator;
import static rescuecore2.standard.entities.StandardEntityURN.AMBULANCE_TEAM;
import static rescuecore2.standard.entities.StandardEntityURN.REFUGE;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import rescuecore2.standard.entities.Building;
import rescuecore2.standard.entities.FireBrigade;
import rescuecore2.standard.entities.Human;
import rescuecore2.standard.entities.StandardEntity;
import rescuecore2.standard.entities.StandardEntityURN;
import rescuecore2.worldmodel.EntityID;
public class CentralizedControlFBAllocator extends FireTargetAllocator {
private Map<EntityID, FireBrigadeInfo> fireBrigadeInfoMap;
private Set<EntityID> taskSet;
private Map<EntityID, EntityID> allocateTaskMap;
private Set<EntityID> finishEntityIDs;
public CentralizedControlFBAllocator(AgentInfo ai, WorldInfo wi, ScenarioInfo si, ModuleManager moduleManager, DevelopData developData) {
super(ai, wi, si, moduleManager, developData);
this.fireBrigadeInfoMap = new HashMap<>();
this.taskSet = new HashSet<>();
this.allocateTaskMap = new HashMap<>();
this.finishEntityIDs = new HashSet<>();
}
@Override
public FireTargetAllocator resume(PrecomputeData precomputeData) {
super.resume(precomputeData);
if (this.getCountResume() >= 2) {
return this;
}
for (EntityID id : this.worldInfo
.getEntityIDsOfType(StandardEntityURN.FIRE_BRIGADE)) {
this.fireBrigadeInfoMap.put(id, new FireBrigadeInfo(id));
}
return this;
}
@Override
public FireTargetAllocator preparate() {
super.preparate();
if (this.getCountPrecompute() >= 2) {
return this;
}
for (EntityID id : this.worldInfo
.getEntityIDsOfType(StandardEntityURN.FIRE_BRIGADE)) {
this.fireBrigadeInfoMap.put(id, new FireBrigadeInfo(id));
}
return this;
}
/**
* calcメソッドで算出した司令内容を返すためのメソッド
*/
@Override
public Map<EntityID, EntityID> getResult() {
return this.convert(this.fireBrigadeInfoMap);
}
/**
* 消防隊情報を
* key:命令対象のエージェントのID
* value:やるべきタスク(市民)のID
* のMapに変換するメソッド
* @param map 消防隊IDと消防隊情報に関連するMap
* @return 司令情報となるMap
*/
private Map<EntityID, EntityID> convert(Map<EntityID, FireBrigadeInfo> map) {
Map<EntityID, EntityID> result = new HashMap<>();
for (EntityID id : map.keySet()) {
FireBrigadeInfo info = map.get(id);
if (info != null && info.target != null) {
result.put(id, info.target);
}
}
return result;
}
/**
* 分散エージェントへの司令内容を算出するためのメソッド
*
* ハンガリアンアルゴリズムを利用して消防隊に担当させるタスクを決定する
*/
@Override
public FireTargetAllocator calc() {
if(this.agentInfo.getTime() < scenarioInfo.getKernelAgentsIgnoreuntil()) return this;
if(this.fireBrigadeInfoMap.keySet().size()==0||this.taskSet.size()==0) return this;
int row = this.fireBrigadeInfoMap.keySet().size();
int col = this.taskSet.size();
boolean reverse = false;
List<EntityID> rowlist = new ArrayList<>(this.fireBrigadeInfoMap.keySet());
List<EntityID> collist = new ArrayList<>(this.taskSet);
if(row > col){
reverse = true;
int tmp = row;
row = col;
col = tmp;
List<EntityID> tmplist = rowlist;
rowlist = collist;
collist = tmplist;
}
int[][] costs = new int[row][col];
for(int i = 0; i<row; i++){
EntityID rowid = rowlist.get(i);
StandardEntity rowposi = this.worldInfo.getPosition(rowid);
for(int j = 0; j<col; j++){
EntityID colid = collist.get(j);
int distance = this.worldInfo.getDistance(rowposi, this.worldInfo.getPosition(colid));
costs[i][j] = distance;
}
}
int[] allocate = Hungarian.execute(costs);
if(reverse){
int tmp = row;
row = col;
col = tmp;
List<EntityID> tmplist = rowlist;
rowlist = collist;
collist = tmplist;
int[] reverse_list = new int[row];
for(int i = 0; i<row; i++) reverse_list[i] = -1;
for(int i = 0; i<col; i++){
reverse_list[allocate[i]] = i;
}
allocate = reverse_list;
}
for(int i = 0; i<row; i++){
if(allocate[i] == -1) continue;
this.fireBrigadeInfoMap.get(rowlist.get(i)).target = collist.get(allocate[i]);
}
//this.printAllocate(allocate, rowlist, collist, row);
return this;
}
/**
* 新しく受信したメッセージから情報を取得するためのメソッド
*
* 埋没市民Setを更新
* 消防隊情報Setを更新
* 消防隊から司令完了を受けたときタスク完了リストを更新
*/
@Override
public FireTargetAllocator updateInfo(MessageManager messageManager) {
super.updateInfo(messageManager);
Set<EntityID> recievetasks = messageManager.getReceivedMessageList(MessageCivilian.class).stream()
.map(e -> {
MessageCivilian mesciv = (MessageCivilian) e;
MessageUtil.reflectMessage(this.worldInfo, mesciv);
return(mesciv);
})
.map(MessageCivilian::getAgentID)
.filter(e -> this.isNeedRescueHuman(this.worldInfo.getEntity(e)))
.filter(e -> !(finishEntityIDs.contains(e)))
.collect(Collectors.toSet());
this.taskSet.addAll(recievetasks);
List<CommunicationMessage> mesfblist = messageManager.getReceivedMessageList(MessageFireBrigade.class);
for(CommunicationMessage mes : mesfblist){
MessageFireBrigade mesfb = (MessageFireBrigade) mes;
MessageUtil.reflectMessage(this.worldInfo, mesfb);
EntityID fbID = mesfb.getAgentID();
FireBrigadeInfo fbi = this.fireBrigadeInfoMap.get(fbID);
fbi.setInfo(mesfb.getTargetID(), mesfb.getPosition(), mesfb.getBuriedness(),
(mesfb.getAction() == MessageFireBrigade.ACTION_RESCUE) ? false : true, this.agentInfo.getTime());
}
List<EntityID> reportlist = messageManager.getReceivedMessageList(MessageReport.class).stream()
.map(MessageReport.class::cast)
.filter(MessageReport::isDone)
.map(MessageReport::getFromID)
.collect(Collectors.toList());
this.finishEntityIDs.addAll(reportlist);
this.taskSet.removeAll(reportlist);
return this;
}
/**
* ある市民について消防隊による救助が必要かを判定するメソッド
*
* @param entity エンティティ
* @return true : 救助必要 false : 救助不必要
*/
private boolean isNeedRescueHuman(StandardEntity entity){
if (entity == null)
return false;
if (!(entity instanceof Human))
return false;
Human target = (Human) entity;
if (!target.isHPDefined() || target.getHP() == 0)
return false;
if (!target.isPositionDefined())
return false;
if (!target.isBuriednessDefined() || target.getBuriedness() == 0)
return false;
StandardEntity position = worldInfo.getPosition(target);
if (position == null)
return false;
StandardEntityURN positionURN = position.getStandardURN();
if (positionURN == REFUGE || positionURN == AMBULANCE_TEAM)
return false;
return true;
}
/**
* ハンガリアンアルゴリズムの割当結果をみるためのメソッド
* @param allocate 消防隊に対応するタスク割当結果配列
* @param rowlist 消防隊IDリスト
* @param collist 埋没市民IDリスト
* @param row 消防隊の数
*/
private void printAllocate(int[] allocate, List<EntityID> rowlist, List<EntityID> collist, int row){
String str = " allocate";
for(int i = 0; i<row; i++){
if(allocate[i] == -1) continue;
str += "\n["+i+"]:"+allocate[i]+" fbID:"+rowlist.get(i)+" tagID:"+collist.get(allocate[i]);
}
System.out.println("[FBCenter] time:"+this.agentInfo.getTime()+" id:"+this.agentInfo.getID()+str);
}
/**
* 消防隊情報クラス
*/
private class FireBrigadeInfo {
EntityID agentID;
EntityID prevtarget;
EntityID position;
int buriedness;
EntityID target;
boolean canNewAction;
int commandTime;
FireBrigadeInfo(EntityID id) {
agentID = id;
prevtarget = null;
position = null;
buriedness = -1;
target = null;
canNewAction = true;
commandTime = -1;
}
/**
* 消防隊に関する情報をセットするメソッド
*/
public void setInfo(EntityID prevtarget, EntityID position, int buriedness, boolean canNewAction, int commandTime){
this.prevtarget = prevtarget;
this.position = position;
this.buriedness = buriedness;
this.canNewAction = canNewAction;
this.commandTime = commandTime;
}
}
}
\ No newline at end of file
package autumn_2023.module.complex;
import static rescuecore2.standard.entities.StandardEntityURN.AMBULANCE_TEAM;
import static rescuecore2.standard.entities.StandardEntityURN.CIVILIAN;
import static rescuecore2.standard.entities.StandardEntityURN.REFUGE;
import adf.core.agent.action.Action;
import adf.core.agent.communication.MessageManager;
import adf.core.agent.communication.standard.bundle.StandardMessageBundle;
import adf.core.agent.communication.standard.bundle.StandardMessagePriority;
import adf.core.agent.communication.standard.bundle.information.MessageBuilding;
import adf.core.agent.communication.standard.bundle.information.MessageCivilian;
import adf.core.agent.communication.standard.bundle.information.MessageFireBrigade;
import adf.core.agent.develop.DevelopData;
import adf.core.agent.info.AgentInfo;
import adf.core.agent.info.ScenarioInfo;
import adf.core.agent.info.WorldInfo;
import adf.core.agent.module.ModuleManager;
import adf.core.component.module.algorithm.Clustering;
import adf.core.component.module.complex.HumanDetector;
import adf.core.debug.DefaultLogger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.log4j.Logger;
import rescuecore2.standard.entities.Building;
import rescuecore2.standard.entities.Civilian;
import rescuecore2.standard.entities.FireBrigade;
import rescuecore2.standard.entities.Human;
import rescuecore2.standard.entities.StandardEntity;
import rescuecore2.standard.entities.StandardEntityURN;
import rescuecore2.worldmodel.EntityID;
public class CentralizedControlFBHumanDetector extends HumanDetector {
private Clustering clustering;
private EntityID result;
private Logger logger;
private MessageManager mm;
public CentralizedControlFBHumanDetector(AgentInfo ai, WorldInfo wi, ScenarioInfo si, ModuleManager moduleManager, DevelopData developData) {
super(ai, wi, si, moduleManager, developData);
logger = DefaultLogger.getLogger(agentInfo.me());
this.clustering = moduleManager.getModule("SampleHumanDetector.Clustering",
"adf.impl.module.algorithm.KMeansClustering");
registerModule(this.clustering);
}
/**
* 新しく受信したメッセージから情報を取得するためのメソッド
*
* 現在のステップで知覚した埋没市民の情報を送信する
* ※ここに消防隊の情報を送信する記述はないが,Tacticsの方で常に送信しているので記述しなくてもいい
*/
@Override
public HumanDetector updateInfo(MessageManager messageManager) {
logger.debug("Time:" + agentInfo.getTime());
super.updateInfo(messageManager);
this.mm = messageManager;
Set<EntityID> changes = this.worldInfo.getChanged().getChangedEntities();
for(EntityID id : changes){
StandardEntity entity = this.worldInfo.getEntity(id);
if(!(entity instanceof Civilian)) continue;
Civilian civ = (Civilian) entity;
if(!this.isNeedRescueHuman(civ)){
continue;
}
StandardMessagePriority level = StandardMessagePriority.NORMAL;
MessageCivilian civ_mes = new MessageCivilian(true, level, civ);
messageManager.addMessage(civ_mes,true);
}
return this;
}
/**
* 救助対象のIDを求めるメソッド
*
* 司令所の司令で行動するため,救助対象を決定しないようにしている
*/
@Override
public HumanDetector calc() {
if(this.agentInfo.getTime() < scenarioInfo.getKernelAgentsIgnoreuntil()) return this;
this.result = null;
return this;
}
private EntityID calcTarget() {
List<Human> rescueTargets = filterRescueTargets(
this.worldInfo.getEntitiesOfType(CIVILIAN));
List<Human> rescueTargetsInCluster = filterInCluster(rescueTargets);
List<Human> targets = rescueTargetsInCluster;
if (targets.isEmpty())
targets = rescueTargets;
logger.debug("Targets:" + targets);
if (!targets.isEmpty()) {
targets.sort(new DistanceSorter(this.worldInfo, this.agentInfo.me()));
Human selected = targets.get(0);
logger.debug("Selected:" + selected);
return selected.getID();
}
return null;
}
/**
* 救助対象IDを返すメソッド
*/
@Override
public EntityID getTarget() {
return this.result;
}
private List<Human>
filterRescueTargets(Collection<? extends StandardEntity> list) {
List<Human> rescueTargets = new ArrayList<>();
for (StandardEntity next : list) {
if (!(next instanceof Human))
continue;
Human h = (Human) next;
if (!isValidHuman(h))
continue;
if (h.getBuriedness() == 0)
continue;
rescueTargets.add(h);
}
return rescueTargets;
}
private List<Human>
filterInCluster(Collection<? extends StandardEntity> entities) {
int clusterIndex = clustering.getClusterIndex(this.agentInfo.getID());
List<Human> filter = new ArrayList<>();
HashSet<StandardEntity> inCluster = new HashSet<>(
clustering.getClusterEntities(clusterIndex));
for (StandardEntity next : entities) {
if (!(next instanceof Human))
continue;
Human h = (Human) next;
if (!h.isPositionDefined())
continue;
StandardEntity position = this.worldInfo.getPosition(h);
if (position == null)
continue;
if (!inCluster.contains(position))
continue;
filter.add(h);
}
return filter;
}
private class DistanceSorter implements Comparator<StandardEntity> {
private StandardEntity reference;
private WorldInfo worldInfo;
DistanceSorter(WorldInfo wi, StandardEntity reference) {
this.reference = reference;
this.worldInfo = wi;
}
public int compare(StandardEntity a, StandardEntity b) {
int d1 = this.worldInfo.getDistance(this.reference, a);
int d2 = this.worldInfo.getDistance(this.reference, b);
return d1 - d2;
}
}
private boolean isValidHuman(StandardEntity entity) {
if (entity == null)
return false;
if (!(entity instanceof Human))
return false;
Human target = (Human) entity;
if (!target.isHPDefined() || target.getHP() == 0)
return false;
if (!target.isPositionDefined())
return false;
if (!target.isDamageDefined() || target.getDamage() == 0)
return false;
if (!target.isBuriednessDefined())
return false;
StandardEntity position = worldInfo.getPosition(target);
if (position == null)
return false;
StandardEntityURN positionURN = position.getStandardURN();
if (positionURN == REFUGE || positionURN == AMBULANCE_TEAM)
return false;
return true;
}
private boolean isNeedRescueHuman(StandardEntity entity){
if (entity == null)
return false;
if (!(entity instanceof Human))
return false;
Human target = (Human) entity;
if (!target.isHPDefined() || target.getHP() == 0)
return false;
if (!target.isPositionDefined())
return false;
if (!target.isBuriednessDefined() || target.getBuriedness() == 0)
return false;
StandardEntity position = worldInfo.getPosition(target);
if (position == null)
return false;
StandardEntityURN positionURN = position.getStandardURN();
if (positionURN == REFUGE || positionURN == AMBULANCE_TEAM)
return false;
return true;
}
}
\ No newline at end of file
package autumn_2023.module.complex;
import adf.core.agent.communication.MessageManager;
import adf.core.agent.develop.DevelopData;
import adf.core.agent.info.AgentInfo;
import adf.core.agent.info.ScenarioInfo;
import adf.core.agent.info.WorldInfo;
import adf.core.agent.module.ModuleManager;
import adf.core.agent.precompute.PrecomputeData;
import adf.core.component.module.complex.AmbulanceTargetAllocator;
import java.util.HashMap;
import java.util.Map;
import rescuecore2.worldmodel.EntityID;
public class SampleAmbulanceTargetAllocator extends AmbulanceTargetAllocator {
public SampleAmbulanceTargetAllocator(AgentInfo ai, WorldInfo wi, ScenarioInfo si, ModuleManager moduleManager, DevelopData developData) {
super(ai, wi, si, moduleManager, developData);
}
@Override
public AmbulanceTargetAllocator resume(PrecomputeData precomputeData) {
super.resume(precomputeData);
return this;
}
@Override
public AmbulanceTargetAllocator preparate() {
super.preparate();
return this;
}
@Override
public Map<EntityID, EntityID> getResult() {
return new HashMap<>();
}
@Override
public AmbulanceTargetAllocator calc() {
return this;
}
@Override
public AmbulanceTargetAllocator updateInfo(MessageManager messageManager) {
super.updateInfo(messageManager);
return this;
}
}
\ No newline at end of file
package autumn_2023.module.complex;
import adf.core.agent.communication.MessageManager;
import adf.core.agent.communication.standard.bundle.StandardMessagePriority;
import adf.core.agent.communication.standard.bundle.centralized.CommandAmbulance;
import adf.core.agent.communication.standard.bundle.information.MessageCivilian;
import adf.core.agent.info.*;
import adf.core.agent.precompute.PrecomputeData;
import adf.core.component.communication.CommunicationMessage;
import adf.core.component.module.complex.Search;
import adf.core.component.module.algorithm.Clustering;
import adf.core.agent.module.ModuleManager;
import adf.core.agent.develop.DevelopData;
import rescuecore2.standard.entities.*;
import rescuecore2.worldmodel.EntityID;
import java.util.*;
import java.util.stream.Collectors;
import static java.lang.Double.POSITIVE_INFINITY;
import static rescuecore2.standard.entities.StandardEntityURN.AMBULANCE_TEAM;
public class SampleSearch extends Search
{
private EntityID result;
private Clustering clustering;
private Set<EntityID> searchedSet = new HashSet<>();
private List<EntityID> list;
private MessageManager messageManager;
private static final int ACTION_LOAD = CommandAmbulance.ACTION_LOAD;
public SampleSearch(
AgentInfo ai, WorldInfo wi, ScenarioInfo si,
ModuleManager mm, DevelopData dd)
{
super(ai, wi, si, mm, dd);
String clusteringKey = "SampleSearch.Clustering.Ambulance";
this.clustering =
mm.getModule(clusteringKey,
"adf.sample.module.algorithm.SampleKMeans");
this.registerModule(this.clustering);
}
@Override
public EntityID getTarget()
{
return this.result;
}
@Override
public Search updateInfo(MessageManager mm)
{
super.updateInfo(mm);
if (this.getCountUpdateInfo() > 1) return this;
// そのステップで受信した(前ステップで送信された)メッセージ一覧
List<CommunicationMessage> messages = mm.getReceivedMessageList();
this.messageManager = mm;
// エージェントが現在位置する建物や道路のIDを取得する
EntityID position = this.agentInfo.getPosition();
// 探索済みの (辿り着いたことがある) 対象を候補から除外する
this.searchedSet.add(position);
return this;
}
@Override
public Search calc()
{
EntityID me = this.agentInfo.getID();
int idx = this.clustering.getClusterIndex(me);
if (idx == -1) {
return this;
}
//System.out.println("time:"+this.agentInfo.getTime()+" id:"+me+" target:"+this.getTarget());
Collection<EntityID> cluster =
this.clustering.getClusterEntityIDs(idx);
if (cluster == null) {
return this;
}
// Listに変換
if (this.result == null){
list = new ArrayList<>(cluster);
//System.out.println(list);
}
// エージェントが現在位置する建物や道路のIDを取得する
EntityID position = this.agentInfo.getPosition();
if (this.getTarget() != null && !position.equals(this.getTarget())) {
return this;
}
// 探索済みの (辿り着いたことがある) 対象を候補から除外する
list.removeAll(this.searchedSet);
// すべての対象が探索済みの場合,候補をリセットする
if (list.size() <= 0) {
this.searchedSet.clear();
list = new ArrayList<>(cluster);
}
double near = Double.MAX_VALUE;
for (EntityID lists : this.list) {
StandardEntity test = this.worldInfo.getEntity(lists);
if(test instanceof Building) {
double distance = this.worldInfo.getDistance(position, lists);
if (distance < near){
near = distance;
this.result = lists;
}
}
}
return this;
}
}
\ No newline at end of file
#!/bin/sh
LOADER="adf.impl.DefaultLoader"
PARAMS=$*
cd `dirname $0`
if [ ! -z "$1" ]; then
./gradlew launch --args="${LOADER} ${PARAMS} -pre 0"
else
echo "Options:"
echo "-tn Team name"
echo "-t [FB],[FS],[PF],[PO],[AT],[AC] Number of agents"
echo "-fb [FB] Number of FireBrigade"
echo "-fs [FS] Number of FireStation"
echo "-pf [PF] Number of PoliceForce"
echo "-po [PO] Number of PoliceOffice"
echo "-at [AT] Number of AmbulanceTeam"
echo "-ac [AC] Number of AmbulanceCentre"
echo "-s [HOST]:[PORT] RCRS server host and port"
echo "-h [HOST] RCRS server host (port:27931)"
echo "-pre [0|1] Precompute flag"
echo "-d [0|1] Debug flag"
echo "-dev [0|1] Development mode"
echo "-mc [FILE] ModuleConfig file name"
echo "-md [JSON] ModuleConfig JSON"
echo "-df [FILE] DevelopData JSON file"
echo "-dd [JSON] DevelopData JSON"
echo "-all [alias] -t -1,-1,-1,-1,-1,-1"
echo "-allp [alias] -t 1,0,1,0,1,0,"
echo "-local [alias] -h localhost"
echo "-precompute [alias] -pre 1"
echo "-debug [alias] -d 1"
echo "-develop [alias] -dev 1"
fi
#!/bin/sh
TEAM=ait
mkdir ../${TEAM}
cp -r src ../${TEAM}
cp -r lib ../${TEAM}
mv ../${TEAM}/lib ../${TEAM}/library
cp -r config ../${TEAM}
cp -r data ../${TEAM}
cd ../${TEAM}
tar cvzf ait.tgz *
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment