Rescue drones

This commit is contained in:
Balazs Toldi 2022-05-26 18:49:49 +02:00
parent 5657baac66
commit 694936bb11
Signed by: Bazsalanszky
GPG key ID: 6C7D440036F99D58
12 changed files with 313 additions and 32 deletions

Binary file not shown.

View file

@ -265,6 +265,10 @@ calc_new_y(AgY,_,Y) :- Y = AgY+2.
// in the future // in the future
//+last_dir(skip) <- .drop_goal(pos) //+last_dir(skip) <- .drop_goal(pos)
+!pos(X,Y) : pos(X,Y) <- .print("I've reached ",X,"x",Y). +!pos(X,Y) : pos(X,Y) <- .print("I've reached ",X,"x",Y).
+!pos(X,Y) : pos(X-1,Y) | pos(X,Y-1) | pos(X+1,Y) | pos(X,Y+1)
<- .print("I've kinda reached ",X,"x",Y).
+!pos(X,Y) : last_dir(skip)
<- .print("I think I've kinda reached ",X,"x",Y).
+!pos(X,Y) : not pos(X,Y) +!pos(X,Y) : not pos(X,Y)
<- !next_step(X,Y); <- !next_step(X,Y);
!pos(X,Y). !pos(X,Y).

View file

@ -47,23 +47,23 @@
/* negotiation for found gold */ /* negotiation for found gold */
+bid(Gold,D,Ag) +bid(Victim,D,Ag)
: .count(bid(Gold,_,_),3) // three bids were received : .count(bid(Victim,_,_),3) // three bids were received
<- .print("bid from ",Ag," for ",Gold," is ",D); <- .print("bid from ",Ag," for ",Victim," is ",D);
!allocate_miner(Gold); !allocate_miner(Victim);
.abolish(bid(Gold,_,_)). .abolish(bid(Victim,_,_)).
+bid(Gold,D,Ag) +bid(Victim,D,Ag)
<- .print("bid from ",Ag," for ",Gold," is ",D). <- .print("bid from ",Ag," for ",Victim," is ",D).
+!allocate_miner(Gold) +!allocate_miner(Victim)
<- .findall(op(Dist,A),bid(Gold,Dist,A),LD); <- .findall(op(Dist,A),bid(Victim,Dist,A),LD);
.min(LD,op(DistCloser,Closer)); .min(LD,op(DistCloser,Closer));
DistCloser < 10000; DistCloser < 10000;
.print("Gold ",Gold," was allocated to ",Closer, " options were ",LD); .print("Victim ",Victim," was allocated to ",Closer, " options were ",LD);
.broadcast(tell,allocated(Gold,Closer)). .broadcast(tell,allocated(Victim,Closer)).
//-Gold[source(_)]. //-Gold[source(_)].
-!allocate_miner(Gold) -!allocate_miner(Victim)
<- .print("could not allocate gold ",Gold). <- .print("could not allocate victim ",Victim).
/* end of simulation plans */ /* end of simulation plans */

181
rescueDrone.asl Normal file
View file

@ -0,0 +1,181 @@
// Agent rescueDrone in project airSeaRescue.mas2j
/* Initial beliefs and rules */
/* Initial goals */
free.
/* Initial goals */
+gsize(_,_) : true
<- !send_init_pos.
+!send_init_pos : pos(X,Y)
<- .print("Position initialised").
+!send_init_pos : not pos(_,_) // if I do not know my position yet
<- .wait("+pos(X,Y)", 500); // wait for it and try again
!!send_init_pos(S).
+victim(X1,Y1)[source(A)] : free &
.my_name(Me) &
pos(X2,Y2)
<- .print("Got victim from ",A," at ",X1,"x",Y1);
operator.dist(X1,Y1,X2,Y2,D); // bid
.send(operator,tell,bid(victim(X1,Y1),D,Me)).
+victim(X1,Y1)[source(A)]
: A \== self & .my_name(Me)
<- .send(operator,tell,bid(victim(X1,Y1),10000,Me)).
// victim allocated to me
@palloc1[atomic]
+allocated(Victim,Ag)[source(operator)]
: .my_name(Ag) & free // I am still free
<- -free;
.print("Victim ",Victim," allocated to ",Ag);
!init_handle(Victim).
// some victim was allocated to me, but I can not
// handle it anymore, re-announce
@palloc2[atomic]
+allocated(Victim,Ag)[source(operator)]
: .my_name(Ag) & not free // I am no longer free
<- .print("I can not handle ",Victim," anymore!");
.print("(Re)announcing ",Victim," to others");
.broadcast(tell,Victim).
@pih1[atomic]
+!init_handle(Victim)
: .desire(around(_,_))
<- .print("Dropping around(_,_) desires and intentions to handle ",Victim);
.drop_desire(around(_,_));
!init_handle(Victim).
@pih2[atomic]
+!init_handle(Victim)
: pos(X,Y)
<- .print("Going for ",Victim);
-+last_checked(X,Y);
!!handle(Victim). // must use !! to perform "handle" as not atomic
+!handle(victim(X,Y))
: not free
<- .print("Handling ",victim(X,Y)," now.");
.broadcast(tell, committed_to(victim(X,Y)));
!pos(X,Y);
.print("Itt vagyok");
!ensure(pick,victim(X,Y));
// broadcast that I got the victim(X,Y), to avoid someone
// else to pursue this victim
.broadcast(tell,picked(victim(X,Y)));
.print("Ez is jó!");
?depot(DX,DY);
.print("Még ez is jó!!!");
!pos(DX,DY);
.print("Sőt, Még ez is jó!!!");
!ensure(drop);
.print("Mindjárt megvaaan!");
-victim(X,Y)[source(_)];
.print("Finish handling ",victim(X,Y));
!pos(X,Y);
!!choose_victim.
// if ensure(pick/drop) failed, pursue another victim
-!handle(G) : G
<- .print("failed to catch victim ",G);
.abolish(G); // ignore source
!!choose_victim.
-!handle(G) : true
<- .print("failed to handle ",G,", it isn't in the BB anyway");
!!choose_victim.
// no known victim to choose from
// become free again to search for victim
+!choose_victim
: not victim(_,_)
<- -+free.
// Finished one victim, but others left
// find the closest victim among the known options,
// that nobody else committed to
+!choose_victim
: victim(_,_)
<- .findall(victim(X,Y),victim(X,Y),LG);
!calc_victim_distance(LG,LD);
.length(LD,LLD); LLD > 0;
.print("Uncommitted victim distances: ",LD,LLD);
.min(LD,d(_,NewG));
.print("Next victim is ",NewG);
!!handle(NewG).
-!choose_victim <- -+free.
+!calc_victim_distance([],[]).
+!calc_victim_distance([victim(GX,GY)|R],[d(D,victim(GX,GY))|RD])
: pos(IX,IY) & not committed_to(victim(GX,GY))
<- operator.dist(IX,IY,GX,GY,D);
!calc_victim_distance(R,RD).
+!calc_victim_distance([_|R],RD)
<- !calc_victim_distance(R,RD).
+!pos(X,Y) : pos(X,Y) <- .print("I've reached ",X,"x",Y).
+!pos(X,Y) : pos(X-1,Y) & not carrying_victim | pos(X,Y-1) & not carrying_victim | pos(X+1,Y) & not carrying_victim | pos(X,Y+1) & not carrying_victim
<- .print("I've kinda reached ",X,"x",Y).
+!pos(X,Y) : not pos(X,Y)
<- !next_step(X,Y);
!pos(X,Y).
+!ensure(pick,_) : cell(X,Y,victim,V)
<- .print("Picking up victim");
do(pick); ?carrying_victim.
// fail if no victim there or not carrying_victim after pick!
// handle(G) will "catch" this failure.
+!ensure(drop) : pos(X,Y) & depot(X,Y)
<- do(drop). //TODO: not ?carrying_victim.
+!next_step(X,Y)
: pos(AgX,AgY)
<- searchDrone.get_direction(AgX, AgY, X, Y, D);
//.print("from ",AgX,"x",AgY," to ", X,"x",Y," -> ",D);
-+last_dir(D);
do(D).
+!next_step(X,Y) : not pos(_,_) // I still do not know my position
<- !next_step(X,Y).
-!next_step(X,Y) : true // failure handling -> start again!
<- .print("Failed next_step to ", X,"x",Y," fixing and trying again!");
-+last_dir(null);
!next_step(X,Y).
// someone else picked up the victim I am going to go,
// so drops the intention and chose another victim
@ppgd[atomic]
+picked(G)[source(A)]
: .desire(handle(G)) | .desire(init_handle(G))
<- .print(A," has taken ",G," that I am pursuing! Dropping my intention.");
.abolish(G);
.drop_desire(handle(G));
!!choose_victim.
// someone else picked up a victim I know about,
// remove from my belief base
+picked(victim(X,Y))
<- -victim(X,Y)[source(_)].
// I perceived unknown victim and I am free, handle it
@pcell[atomic] // atomic: so as not to handle another
// event until handle victim is initialised
+cell(X,Y,victim,V)
: not carrying_victim & free
<- -free;
+victim(X,Y);
.print("Victim perceived: ",victim(X,Y));
!init_handle(victim(X,Y)).
+cell(X,Y,victim,V)
: not victim(X,Y)
<- +victim(X,Y);
.print("Announcing ",victim(X,Y)," to others");
.broadcast(tell,victim(X,Y));
.send(V,tell,stayHere(X,Y)).
+free : pos(AgX,AgY)
<-
victim.get_direction(AgX, AgY, D);
do(D).

View file

@ -101,6 +101,8 @@ calc_new_y(AgY,_,Y) :- Y = AgY+2.
/* Finding victims */ /* Finding victims */
+cell(X,Y,victim,V): true +cell(X,Y,victim,V): true
<- .print("Found vimctim",V); <- .print("Found vimctim",V);
.send(V,tell,stayHere(X,Y)). .print("Announcing ",victim(X,Y)," to others");
.broadcast(tell,victim(X,Y));
.send(V,tell,stayHere(X,Y)).

View file

@ -3,6 +3,8 @@ package common;
public class Constants { public class Constants {
public static int victimCount = 4; public static int victimCount = 4;
public static int searchDroneCount = 2; public static int searchDroneCount = 2;
public static int rescueDroneCount = 3;
private Constants(){} private Constants() {
}
} }

View file

@ -42,6 +42,7 @@ public class WorldEnvironment extends Environment {
model = WorldModel.senario1(); model = WorldModel.senario1();
clearPercepts(); clearPercepts();
addPercept(Literal.parseLiteral("gsize(" + model.getWidth() + "," + model.getHeight() + ")")); addPercept(Literal.parseLiteral("gsize(" + model.getWidth() + "," + model.getHeight() + ")"));
addPercept(Literal.parseLiteral("depot(" + (model.getWidth()-1) + "," + (model.getHeight()-1) + ")"));
updateAgents(); updateAgents();
informAgsEnvironmentChanged(); informAgsEnvironmentChanged();
} }
@ -69,7 +70,9 @@ public class WorldEnvironment extends Environment {
clearPercepts(agName); clearPercepts(agName);
// its location // its location
Location l = model.getAgPos(ag); Location l = model.getAgPos(ag);
if (model.agWithVictim.contains(ag)) {
addPercept(agName, Literal.parseLiteral("carrying_victim"));
}
addPercept(agName, Literal.parseLiteral("pos(" + l.x + "," + l.y + ")")); addPercept(agName, Literal.parseLiteral("pos(" + l.x + "," + l.y + ")"));
updateAgPercept(agName, l.x - 1, l.y - 1); updateAgPercept(agName, l.x - 1, l.y - 1);
updateAgPercept(agName, l.x - 1, l.y); updateAgPercept(agName, l.x - 1, l.y);
@ -94,7 +97,7 @@ public class WorldEnvironment extends Environment {
addPercept(agName, Literal.parseLiteral("cell(" + x + "," + y + ",enemy)")); addPercept(agName, Literal.parseLiteral("cell(" + x + "," + y + ",enemy)"));
} }
if (model.hasObject(WorldModel.AGENT, x, y)) { if (model.hasObject(WorldModel.AGENT, x, y)) {
if(agName.startsWith("searchDrone")) { if(agName.startsWith("searchDrone") || agName.startsWith("rescueDrone")) {
for (int i = 0; i < Constants.victimCount; i++) { for (int i = 0; i < Constants.victimCount; i++) {
Location victimLocation = model.getAgPos(i); Location victimLocation = model.getAgPos(i);
if(victimLocation.x == x && victimLocation.y == y){ if(victimLocation.x == x && victimLocation.y == y){
@ -122,9 +125,10 @@ public class WorldEnvironment extends Environment {
try { try {
if (sleep > 0) { if (sleep > 0) {
Thread.sleep(sleep); Thread.sleep(sleep);
}else {
Thread.sleep(10);
} }
int agId = getAgIdBasedOnName(ag); int agId = getAgIdBasedOnName(ag);
if (action.equals(up)) { if (action.equals(up)) {
result = model.move(Move.UP, agId); result = model.move(Move.UP, agId);
} else if (action.equals(down)) { } else if (action.equals(down)) {
@ -135,7 +139,11 @@ public class WorldEnvironment extends Environment {
result = model.move(Move.LEFT, agId); result = model.move(Move.LEFT, agId);
} else if (action.equals(skip)) { } else if (action.equals(skip)) {
result = true; result = true;
} else if (action.getFunctor().equals("decLife")) { }else if (action.equals(pick)) {
result = model.pick(agId);
} else if (action.equals(drop)) {
result = model.drop(agId);
}else if (action.getFunctor().equals("decLife")) {
int life = (int) ((NumberTerm) action.getTerm(0)).solve(); int life = (int) ((NumberTerm) action.getTerm(0)).solve();
System.out.println(life); System.out.println(life);
result = true; result = true;
@ -146,6 +154,7 @@ public class WorldEnvironment extends Environment {
} }
if (result) { if (result) {
updateAgPercept(agId); updateAgPercept(agId);
view.updateRescuedVictims();
return true; return true;
} }
} catch (Exception e) { } catch (Exception e) {
@ -163,6 +172,9 @@ public class WorldEnvironment extends Environment {
if (agName.startsWith("searchDrone")) { if (agName.startsWith("searchDrone")) {
return i + Constants.victimCount; return i + Constants.victimCount;
} }
if (agName.startsWith("rescueDrone")) {
return i + Constants.victimCount+Constants.searchDroneCount;
}
return -1; return -1;
} }
@ -171,6 +183,8 @@ public class WorldEnvironment extends Environment {
return "victim"+(i+1); return "victim"+(i+1);
} else if (i < Constants.victimCount+Constants.searchDroneCount) { } else if (i < Constants.victimCount+Constants.searchDroneCount) {
return "searchDrone"+(i-(Constants.victimCount-1)); return "searchDrone"+(i-(Constants.victimCount-1));
} else if (i < Constants.victimCount+Constants.searchDroneCount+Constants.rescueDroneCount) {
return "rescueDrone"+(i-(Constants.victimCount+Constants.searchDroneCount-1));
} }
return ""; return "";
} }

View file

@ -1,9 +1,12 @@
package operator; package operator;
import common.Constants;
import jason.environment.grid.GridWorldModel; import jason.environment.grid.GridWorldModel;
import jason.environment.grid.Location; import jason.environment.grid.Location;
import java.util.HashSet;
import java.util.Random; import java.util.Random;
import java.util.Set;
public class WorldModel extends GridWorldModel { public class WorldModel extends GridWorldModel {
@ -11,8 +14,9 @@ public class WorldModel extends GridWorldModel {
public static final int VICTIM = 16; public static final int VICTIM = 16;
public static final int DEPOT = 32; public static final int DEPOT = 32;
public static final int ENEMY = 64; public static final int ENEMY = 64;
public int rescuedVictims = 0;
protected static WorldModel model = null; protected static WorldModel model = null;
Set<Integer> agWithVictim = new HashSet<Integer>();
public WorldModel(int w, int h, int nbAgs) { public WorldModel(int w, int h, int nbAgs) {
super(w, h, nbAgs); super(w, h, nbAgs);
@ -20,19 +24,24 @@ public class WorldModel extends GridWorldModel {
static WorldModel senario1() { static WorldModel senario1() {
WorldModel result = new WorldModel(35, 35, 6); WorldModel result = new WorldModel(35, 35, Constants.victimCount + Constants.searchDroneCount + Constants.rescueDroneCount);
Random random1 = new Random(); Random random1 = new Random();
for (int i = 0; i <= 4; i++) { for (int i = 0; i <= 4; i++) {
result.add(WorldModel.OBSTACLE, random1.nextInt(34), random1.nextInt(34)); //result.add(WorldModel.OBSTACLE, random1.nextInt(34), random1.nextInt(34));
} }
// Victim agents
result.setAgPos(0, 1, 0); result.setAgPos(0, 1, 0);
result.setAgPos(1, 20, 0); result.setAgPos(1, 20, 0);
result.setAgPos(2, 3, 20); result.setAgPos(2, 3, 20);
result.setAgPos(3, 20, 20); result.setAgPos(3, 20, 20);
System.out.println(result.getNbOfAgs()); // Search Drone agents
result.setAgPos(4,33,34); result.setAgPos(4, 33, 34);
result.setAgPos(5,0,34); result.setAgPos(5, 0, 34);
result.add(DEPOT,34,34); // Rescue Drone agents
result.setAgPos(6, 18, 33);
result.setAgPos(7, 19, 33);
result.setAgPos(8, 17, 33);
result.add(DEPOT, 34, 34);
model = result; model = result;
return result; return result;
} }
@ -64,6 +73,62 @@ public class WorldModel extends GridWorldModel {
return true; return true;
} }
private int getAgentIdByLocation(Location l) {
for (int i = 0; i < getNbOfAgs(); i++) {
if (agPos[i].x == l.x && agPos[i].y == l.y) return i;
}
return -1;
}
public boolean pick(int ag) {
boolean result = false;
Location l = getAgPos(ag);
result = pickLocation(ag, new Location(l.x - 1, l.y - 1));
if (!result)
result = pickLocation(ag, new Location(l.x - 1, l.y));
if (!result)
result = pickLocation(ag, new Location(l.x - 1, l.y + 1));
if (!result)
result = pickLocation(ag, new Location(l.x, l.y - 1));
if (!result)
result = pickLocation(ag, new Location(l.x, l.y + 1));
if (!result)
result = pickLocation(ag, new Location(l.x + 1, l.y - 1));
if (!result)
result = pickLocation(ag, new Location(l.x + 1, l.y));
if (!result)
result = pickLocation(ag, new Location(l.x + 1, l.y + 1));
if(!result)
System.out.println("Na itt baj van....");
return result;
}
public boolean pickLocation(int ag, Location l) {
if (hasObject(WorldModel.AGENT, l.x, l.y)) {
if (!agWithVictim.contains(ag) && getAgentIdByLocation(l) < Constants.victimCount) {
remove(WorldModel.AGENT, l.x, l.y);
agWithVictim.add(ag);
return true;
}
}
return false;
}
public boolean drop(int ag) {
Location l = getAgPos(ag);
if (hasObject(WorldModel.DEPOT, l.x, l.y)
|| hasObject(WorldModel.DEPOT, l.x - 1, l.y)
|| hasObject(WorldModel.DEPOT, l.x, l.y - 1)
|| hasObject(WorldModel.DEPOT, l.x + 1, l.y)
|| hasObject(WorldModel.DEPOT, l.x, l.y + 1)) {
agWithVictim.remove(ag);
rescuedVictims++;
return true;
}
return false;
}
@Override @Override
public Location getAgPos(int ag) { public Location getAgPos(int ag) {
return super.getAgPos(ag); return super.getAgPos(ag);
@ -86,4 +151,8 @@ public class WorldModel extends GridWorldModel {
public static void destroy() { public static void destroy() {
model = null; model = null;
} }
public int getRescuedVictims() {
return rescuedVictims;
}
} }

View file

@ -1,5 +1,6 @@
package operator; package operator;
import common.Constants;
import jason.environment.grid.GridWorldModel; import jason.environment.grid.GridWorldModel;
import jason.environment.grid.GridWorldView; import jason.environment.grid.GridWorldView;
@ -125,11 +126,12 @@ public class WorldView extends GridWorldView {
} }
} }
}); });
} }
public void udpateCollectedGolds() { public void updateRescuedVictims() {
WorldModel wm = (WorldModel) model; WorldModel wm = (WorldModel) model;
//jGoldsC.setText(wm.getGoldsInDepot() + "/" + wm.getInitialNbGolds()); jGoldsC.setText(String.valueOf(wm.getRescuedVictims()));
} }
@Override @Override
@ -144,22 +146,29 @@ public class WorldView extends GridWorldView {
case WorldModel.ENEMY: case WorldModel.ENEMY:
drawEnemy(g, x, y); drawEnemy(g, x, y);
break; break;
default:
drawEmpty(g,x,y);
} }
} }
@Override @Override
public void drawAgent(Graphics g, int x, int y, Color c, int id) { public void drawAgent(Graphics g, int x, int y, Color c, int id) {
Color idColor = Color.black; Color idColor = Color.black;
if(id <4){ int idOffset = 0;
if(id < Constants.victimCount){
idColor = Color.RED; idColor = Color.RED;
} else if (id < 6) { } else if (id < Constants.victimCount+Constants.searchDroneCount) {
idColor = Color.MAGENTA; idColor = Color.MAGENTA;
idOffset = Constants.victimCount;
} else if (id < Constants.victimCount+Constants.searchDroneCount+Constants.rescueDroneCount){
idColor = Color.ORANGE;
idOffset = Constants.victimCount+Constants.searchDroneCount;
} }
super.drawAgent(g, x, y, idColor, -1); super.drawAgent(g, x, y, idColor, -1);
idColor = Color.white; idColor = Color.white;
//} //}
g.setColor(idColor); g.setColor(idColor);
drawString(g, x, y, defaultFont, String.valueOf(id + 1)); drawString(g, x, y, defaultFont, String.valueOf(id + 1-idOffset));
} }
public void drawDepot(Graphics g, int x, int y) { public void drawDepot(Graphics g, int x, int y) {