From a3014f68da920d8dd8efbf29394b7280e0ac4586 Mon Sep 17 00:00:00 2001 From: K20014 <82937878+K20014@users.noreply.github.com> Date: Wed, 1 Nov 2023 14:37:49 +0900 Subject: [PATCH] =?UTF-8?q?=E4=BD=9C=E6=A5=AD=E4=BF=9D=E5=AD=98=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AuctionCommandExecutorAmbulance.java | 308 ++++++++++++++++++ .../AuctionCommandPickerAmbulance.java | 78 +++++ .../module/comm/AuctionChannelSubscriber.java | 99 ++++++ .../comm/AuctionMessageCoordinator.java | 211 ++++++++++++ .../module/comm/infomation/MessageATCost.java | 77 +++++ .../complex/AuctionATHumanDetector.java | 240 ++++++++++++++ ...a => AuctionAmbulanceTargetAllocator.java} | 4 +- src/main/java/sample_team/.DS_Store | Bin 0 -> 6148 bytes .../java/sample_team/module/complex/.DS_Store | Bin 0 -> 6148 bytes 9 files changed, 1015 insertions(+), 2 deletions(-) create mode 100644 src/main/java/autumn_2023/centralized/AuctionCommandExecutorAmbulance.java create mode 100644 src/main/java/autumn_2023/centralized/AuctionCommandPickerAmbulance.java create mode 100644 src/main/java/autumn_2023/module/comm/AuctionChannelSubscriber.java create mode 100644 src/main/java/autumn_2023/module/comm/AuctionMessageCoordinator.java create mode 100644 src/main/java/autumn_2023/module/comm/infomation/MessageATCost.java create mode 100644 src/main/java/autumn_2023/module/complex/AuctionATHumanDetector.java rename src/main/java/autumn_2023/module/complex/{SampleAmbulanceTargetAllocator.java => AuctionAmbulanceTargetAllocator.java} (83%) create mode 100644 src/main/java/sample_team/.DS_Store create mode 100644 src/main/java/sample_team/module/complex/.DS_Store diff --git a/src/main/java/autumn_2023/centralized/AuctionCommandExecutorAmbulance.java b/src/main/java/autumn_2023/centralized/AuctionCommandExecutorAmbulance.java new file mode 100644 index 0000000..ee7cc12 --- /dev/null +++ b/src/main/java/autumn_2023/centralized/AuctionCommandExecutorAmbulance.java @@ -0,0 +1,308 @@ +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.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.MessageReport; +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.centralized.CommandExecutor; +import adf.core.component.extaction.ExtAction; +import adf.core.component.module.algorithm.PathPlanning; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import rescuecore2.standard.entities.Area; +import rescuecore2.standard.entities.Human; +import rescuecore2.standard.entities.StandardEntity; +import rescuecore2.worldmodel.EntityID; + +public class AuctionCommandExecutorAmbulance extends CommandExecutor{ + 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 PathPlanning pathPlanning; + + private ExtAction actionTransport; + private ExtAction actionExtMove; + + private int commandType; + private EntityID target; + private EntityID commanderID; + + public AuctionCommandExecutorAmbulance(AgentInfo ai, WorldInfo wi, ScenarioInfo si, ModuleManager moduleManager, DevelopData developData) { + super(ai, wi, si, moduleManager, developData); + this.commandType = ACTION_UNKNOWN; + switch (scenarioInfo.getMode()) { + case PRECOMPUTATION_PHASE: + case PRECOMPUTED: + case NON_PRECOMPUTE: + this.pathPlanning = moduleManager.getModule( + "DefaultCommandExecutorAmbulance.PathPlanning", + "adf.impl.module.algorithm.DijkstraPathPlanning"); + this.actionTransport = moduleManager.getExtAction( + "DefaultCommandExecutorAmbulance.ExtActionTransport", + "adf.impl.extaction.DefaultExtActionTransport"); + this.actionExtMove = moduleManager.getExtAction( + "DefaultCommandExecutorAmbulance.ExActionMove", + "adf.impl.extaction.DefaultExtActionMove"); + break; + } + } + + + @Override + public CommandExecutor setCommand(CommandAmbulance 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(); + } + return this; + } + + + @Override + public CommandExecutor updateInfo(MessageManager messageManager) { + super.updateInfo(messageManager); + if (this.getCountUpdateInfo() >= 2) { + return this; + } + this.pathPlanning.updateInfo(messageManager); + this.actionTransport.updateInfo(messageManager); + this.actionExtMove.updateInfo(messageManager); + + if (this.isCommandCompleted()) { + 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 { + this.commandType = ACTION_UNKNOWN; + this.target = null; + this.commanderID = null; + } + } + } + return this; + } + + + @Override + public CommandExecutor precompute(PrecomputeData precomputeData) { + super.precompute(precomputeData); + if (this.getCountPrecompute() >= 2) { + return this; + } + this.pathPlanning.precompute(precomputeData); + this.actionTransport.precompute(precomputeData); + this.actionExtMove.precompute(precomputeData); + return this; + } + + + @Override + public CommandExecutor resume(PrecomputeData precomputeData) { + super.resume(precomputeData); + if (this.getCountResume() >= 2) { + return this; + } + this.pathPlanning.resume(precomputeData); + this.actionTransport.resume(precomputeData); + this.actionExtMove.resume(precomputeData); + return this; + } + + + @Override + public CommandExecutor preparate() { + super.preparate(); + if (this.getCountPreparate() >= 2) { + return this; + } + this.pathPlanning.preparate(); + this.actionTransport.preparate(); + this.actionExtMove.preparate(); + return this; + } + + + @Override + public CommandExecutor calc() { + this.result = null; + switch (this.commandType) { + case ACTION_REST: + EntityID position = this.agentInfo.getPosition(); + if (this.target == null) { + Collection< + EntityID> refuges = this.worldInfo.getEntityIDsOfType(REFUGE); + if (refuges.contains(position)) { + this.result = new ActionRest(); + } else { + this.pathPlanning.setFrom(position); + this.pathPlanning.setDestination(refuges); + List path = this.pathPlanning.calc().getResult(); + if (path != null && path.size() > 0) { + this.result = new ActionMove(path); + } else { + this.result = new ActionRest(); + } + } + return this; + } + if (position.getValue() != this.target.getValue()) { + List path = this.pathPlanning.getResult(position, + this.target); + if (path != null && path.size() > 0) { + this.result = new ActionMove(path); + return this; + } + } + this.result = new ActionRest(); + return this; + case ACTION_MOVE: + if (this.target != null) { + 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(); + } + return this; + case ACTION_AUTONOMY: + if (this.target == null) { + return this; + } + 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(); + } + } else if (targetEntity instanceof Human) { + this.result = this.actionTransport.setTarget(this.target).calc() + .getAction(); + } + } + return this; + } + + + private boolean isCommandCompleted() { + Human agent = (Human) this.agentInfo.me(); + switch (this.commandType) { + case ACTION_REST: + if (this.target == null) { + return (agent.getDamage() == 0); + } + if (Objects.requireNonNull(this.worldInfo.getEntity(this.target)) + .getStandardURN() == REFUGE) { + if (agent.getPosition().getValue() == this.target.getValue()) { + return (agent.getDamage() == 0); + } + } + return false; + case ACTION_MOVE: + return this.target == null || this.agentInfo.getPosition() + .getValue() == this.target.getValue(); + case ACTION_RESCUE: + if (this.target == null) { + return true; + } + 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(); + } 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(); + } + } + return true; + } + return true; + } +} diff --git a/src/main/java/autumn_2023/centralized/AuctionCommandPickerAmbulance.java b/src/main/java/autumn_2023/centralized/AuctionCommandPickerAmbulance.java new file mode 100644 index 0000000..f371862 --- /dev/null +++ b/src/main/java/autumn_2023/centralized/AuctionCommandPickerAmbulance.java @@ -0,0 +1,78 @@ +package autumn_2023.centralized; + +import adf.core.agent.communication.standard.bundle.centralized.CommandAmbulance; +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 AuctionCommandPickerAmbulance extends CommandPicker{ + private int scoutDistance; + + private Collection messages; + private Map allocationData; + + public AuctionCommandPickerAmbulance(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.DefaultCommandPickerAmbulance.scoutDistance", + 40000); + } + + + @Override + public CommandPicker + setAllocatorResult(Map allocationData) { + this.allocationData = allocationData; + return this; + } + + + @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.AMBULANCE_TEAM) { + StandardEntity target = this.worldInfo + .getEntity(this.allocationData.get(agentID)); + if (target != null) { + if (target instanceof Human) { + CommandAmbulance command = new CommandAmbulance(true, agentID, + target.getID(), CommandAmbulance.ACTION_AUTONOMY); + this.messages.add(command); + } else if (target instanceof Area) { + CommandScout command = new CommandScout(true, agentID, + target.getID(), this.scoutDistance); + this.messages.add(command); + } + } + } + } + return this; + } + + + @Override + public Collection getResult() { + return this.messages; + } +} diff --git a/src/main/java/autumn_2023/module/comm/AuctionChannelSubscriber.java b/src/main/java/autumn_2023/module/comm/AuctionChannelSubscriber.java new file mode 100644 index 0000000..f77d070 --- /dev/null +++ b/src/main/java/autumn_2023/module/comm/AuctionChannelSubscriber.java @@ -0,0 +1,99 @@ +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 AuctionChannelSubscriber 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)); + } + } +} diff --git a/src/main/java/autumn_2023/module/comm/AuctionMessageCoordinator.java b/src/main/java/autumn_2023/module/comm/AuctionMessageCoordinator.java new file mode 100644 index 0000000..63f4246 --- /dev/null +++ b/src/main/java/autumn_2023/module/comm/AuctionMessageCoordinator.java @@ -0,0 +1,211 @@ +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 autumn_2023.module.comm.infomation.MessageATCost; + +import java.util.ArrayList; +import java.util.List; +import rescuecore2.standard.entities.StandardEntityURN; + +public class AuctionMessageCoordinator extends MessageCoordinator{ + @Override + public void coordinate(AgentInfo agentInfo, WorldInfo worldInfo, + ScenarioInfo scenarioInfo, MessageManager messageManager, + ArrayList sendMessageList, + List> channelSendMessageList) { + + // have different lists for every agent + ArrayList policeMessages = new ArrayList<>(); + ArrayList ambulanceMessages = new ArrayList<>(); + ArrayList fireBrigadeMessages = new ArrayList<>(); + + ArrayList 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) { + 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); + } else if (msg instanceof MessageATCost) { + // 新規メッセージクラス + ambulanceMessages.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 voiceMessageLowList = new ArrayList<>(); + ArrayList voiceMessageNormalList = new ArrayList<>(); + ArrayList 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] = AuctionChannelSubscriber.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 messages, + List> 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); + } + } + } + } +} diff --git a/src/main/java/autumn_2023/module/comm/infomation/MessageATCost.java b/src/main/java/autumn_2023/module/comm/infomation/MessageATCost.java new file mode 100644 index 0000000..f4ecbca --- /dev/null +++ b/src/main/java/autumn_2023/module/comm/infomation/MessageATCost.java @@ -0,0 +1,77 @@ +package autumn_2023.module.comm.infomation; + +import javax.annotation.Nonnull; + +import adf.core.agent.communication.standard.bundle.StandardMessage; +import adf.core.agent.communication.standard.bundle.StandardMessagePriority; +import adf.core.component.communication.util.BitOutputStream; +import adf.core.component.communication.util.BitStreamReader; +import rescuecore2.worldmodel.EntityID; + +public class MessageATCost extends StandardMessage{ + + // int型の容量(32bit)? + public static final int SIZE_COST = 32; + public static final int SIZE_TARGET = 32; + public static final int SIZE_RESULT = 32; + + private final EntityID targetId; + private final EntityID resultId; + private final int cost; + + public MessageATCost(boolean isRadio, EntityID tagrgetId, EntityID resultId, int cost) { + super(isRadio, StandardMessagePriority.NORMAL); + this.targetId = tagrgetId; + this.resultId = resultId; + this.cost = cost; + } + + public MessageATCost(boolean isRadio, StandardMessagePriority sendingPriority, EntityID tagrgetId, EntityID resultId, int cost) { + super(isRadio, sendingPriority); + this.targetId = tagrgetId; + this.resultId = resultId; + this.cost = cost; + } + + public MessageATCost(boolean isRadio, int from, int ttl, @Nonnull BitStreamReader bitStreamReader) { + super(isRadio, from, ttl, bitStreamReader); + this.targetId = new EntityID(bitStreamReader.getBits(SIZE_TARGET)); + this.resultId = new EntityID(bitStreamReader.getBits(SIZE_RESULT)); + this.cost = bitStreamReader.getBits(SIZE_COST); + } + + public EntityID getTargetID() { + return targetId; + } + + public EntityID getResultID() { + return resultId; + } + + public int cost() { + return cost; + } + + @Override + public int getByteArraySize() { + return this.toBitOutputStream().size(); + } + + @Override + public byte[] toByteArray() { + return this.toBitOutputStream().toByteArray(); + } + + @Override + public BitOutputStream toBitOutputStream() { + final BitOutputStream bitOutputStream = new BitOutputStream(); + bitOutputStream.writeBits(this.targetId.getValue(), SIZE_TARGET); + bitOutputStream.writeBits(this.cost, SIZE_COST); + return bitOutputStream; + } + + @Override + public String getCheckKey() { + return String.format("TargetID : " + this.targetId.getValue() + " Cost : " + this.cost); + } +} diff --git a/src/main/java/autumn_2023/module/complex/AuctionATHumanDetector.java b/src/main/java/autumn_2023/module/complex/AuctionATHumanDetector.java new file mode 100644 index 0000000..35017ce --- /dev/null +++ b/src/main/java/autumn_2023/module/complex/AuctionATHumanDetector.java @@ -0,0 +1,240 @@ +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.action.ambulance.ActionLoad; +import adf.core.agent.action.ambulance.ActionRescue; +import adf.core.agent.action.ambulance.ActionUnload; +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.StandardMessagePriority; +import adf.core.agent.communication.standard.bundle.information.MessageAmbulanceTeam; +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 autumn_2023.module.comm.infomation.MessageATCost; + +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.AmbulanceCentre; +import rescuecore2.standard.entities.AmbulanceTeam; +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 AuctionATHumanDetector extends HumanDetector { + + private Clustering clustering; + + private EntityID result; + + private Logger logger; + + // 救急司令所からの埋没市民のメッセージリスト + private List receivedCentreCivilian = new ArrayList<>(); + + public AuctionATHumanDetector(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) { + super.updateInfo(messageManager); + + // そのステップで受信した(前ステップで送信された)メッセージ一覧 + List messages = messageManager.getReceivedMessageList(); + // messageManager.refresh(); + for(CommunicationMessage ms : messages) { + // msが市民の情報であれば + if (ms instanceof MessageCivilian) { + MessageCivilian msCiv = (MessageCivilian) ms; + if (this.worldInfo.getEntity(msCiv.getSenderID()) instanceof AmbulanceCentre) + receivedCentreCivilian.add(msCiv.getAgentID()); + } + } + for(EntityID receive : receivedCentreCivilian) { + int taskcost = this.worldInfo.getDistance(this.agentInfo.getID(), receive); + if (taskcost == 0) continue; + // 新規メッセージクラスを用いて救急司令所に送信 + CommunicationMessage costmes = new MessageATCost(true, StandardMessagePriority.HIGH, receive, this.result, taskcost); + messageManager.addMessage(costmes); + } + + // このステップ内で知覚したエンティティのうち,救助対象の市民リストを作成 + Set changed = this.worldInfo.getChanged().getChangedEntities(); + List changedRescueTargets = filterRescueTargets((Collection)changed); + + // 司令所に送るメッセージを作成・送信(現状:救急司令所のみ) + // 市民の情報を送信 + for(EntityID change : changedRescueTargets) { + Civilian changeCivilian = (Civilian)this.worldInfo.getEntity(change); + CommunicationMessage message = new MessageCivilian(true, StandardMessagePriority.HIGH, changeCivilian); + messageManager.addMessage(message); + } + // 自身の情報を送信 + CommunicationMessage changeMe = new MessageAmbulanceTeam(true, StandardMessagePriority.HIGH, (AmbulanceTeam)this.worldInfo.getEntity(this.agentInfo.getID()), convertActionAmbulance(), this.result); + messageManager.addMessage(changeMe); + + return this; + } + + + @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 rescueTargets = filterRescueTargets(this.worldInfo.getEntitiesOfType(CIVILIAN)); + List rescueTargetsInCluster = filterInCluster(rescueTargets); + List 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; + } + + + @Override + public EntityID getTarget() { + return this.result; + } + + + private List filterRescueTargets(Collection list) { + List 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 filterInCluster(Collection entities) { + int clusterIndex = clustering.getClusterIndex(this.agentInfo.getID()); + List filter = new ArrayList<>(); + HashSet 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 { + + 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 int convertActionAmbulance(){ + int convertaction = 0; + if (this.agentInfo.getTime() > 1) + { + Action agentAction = this.agentInfo.getExecutedAction(this.agentInfo.getTime()-1); + if (agentAction instanceof ActionRest) { + convertaction = 0; + }else if (agentAction instanceof ActionMove) { + convertaction = 1; + }else if (agentAction instanceof ActionRescue) { + convertaction = 2; + }else if (agentAction instanceof ActionLoad) { + convertaction = 3; + }else if (agentAction instanceof ActionUnload) { + convertaction = 4; + } + } + return convertaction; + } +} \ No newline at end of file diff --git a/src/main/java/autumn_2023/module/complex/SampleAmbulanceTargetAllocator.java b/src/main/java/autumn_2023/module/complex/AuctionAmbulanceTargetAllocator.java similarity index 83% rename from src/main/java/autumn_2023/module/complex/SampleAmbulanceTargetAllocator.java rename to src/main/java/autumn_2023/module/complex/AuctionAmbulanceTargetAllocator.java index 453de8a..1200152 100755 --- a/src/main/java/autumn_2023/module/complex/SampleAmbulanceTargetAllocator.java +++ b/src/main/java/autumn_2023/module/complex/AuctionAmbulanceTargetAllocator.java @@ -12,9 +12,9 @@ import java.util.HashMap; import java.util.Map; import rescuecore2.worldmodel.EntityID; -public class SampleAmbulanceTargetAllocator extends AmbulanceTargetAllocator { +public class AuctionAmbulanceTargetAllocator extends AmbulanceTargetAllocator { - public SampleAmbulanceTargetAllocator(AgentInfo ai, WorldInfo wi, ScenarioInfo si, ModuleManager moduleManager, DevelopData developData) { + public AuctionAmbulanceTargetAllocator(AgentInfo ai, WorldInfo wi, ScenarioInfo si, ModuleManager moduleManager, DevelopData developData) { super(ai, wi, si, moduleManager, developData); } diff --git a/src/main/java/sample_team/.DS_Store b/src/main/java/sample_team/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0