Better search drone logic

This commit is contained in:
Balazs Toldi 2022-05-26 11:14:05 +02:00
parent 923ae73b5e
commit 5657baac66
Signed by: Bazsalanszky
GPG key ID: 6C7D440036F99D58
11 changed files with 58 additions and 213 deletions

Binary file not shown.

View file

@ -17,8 +17,10 @@ MAS airSeaRescue {
agents:
victim#4;
searchDrone#2;
rescueDrone#3;
operator;
}

View file

@ -99,178 +99,8 @@ calc_new_y(AgY,_,Y) :- Y = AgY+2.
!next_step(X,Y).
/* Gold-searching Plans */
// I perceived unknown gold and I am free, handle it
@pcell[atomic] // atomic: so as not to handle another
// event until handle gold is initialised
+cell(X,Y,gold)
: not carrying_gold & free
<- -free;
+gold(X,Y);
.print("Gold perceived: ",gold(X,Y));
!init_handle(gold(X,Y)).
// if I see gold and I'm not free but also not carrying gold yet
// (I'm probably going towards one), abort handle(gold) and pick up
// this one which is nearer
@pcell2[atomic]
+cell(X,Y,gold)
: not carrying_gold & not free &
.desire(handle(gold(OldX,OldY))) & // I desire to handle another gold which
pos(AgX,AgY) &
operator.dist(X, Y, AgX,AgY,DNewG) &
operator.dist(OldX,OldY,AgX,AgY,DOldG) &
DNewG < DOldG // is farther than the one just perceived
<- +gold(X,Y);
.drop_desire(handle(gold(OldX,OldY)));
.print("Giving up current gold ",gold(OldX,OldY),
" to handle ",gold(X,Y)," which I am seeing!");
.print("Announcing ",gold(OldX,OldY)," to others");
.broadcast(tell,gold(OldX,OldY));
.broadcast(untell, committed_to(gold(OldX,OldY)));
!init_handle(gold(X,Y)).
// I am not free, just add gold belief and announce to others
+cell(X,Y,gold)
: not gold(X,Y) & not committed_to(gold(X,Y))
<- +gold(X,Y);
.print("Announcing ",gold(X,Y)," to others");
.broadcast(tell,gold(X,Y)).
// someone else sent me a gold location
+gold(X1,Y1)[source(A)]
: A \== self &
not allocated(gold(X1,Y1),_) & // The gold was not allocated yet
not carrying_gold & // I am not carrying gold
free & // and I am free
pos(X2,Y2) &
.my_name(Me)
<- operator.dist(X1,Y1,X2,Y2,D); // bid
.send(leader,tell,bid(gold(X1,Y1),D,Me)).
// bid high as I'm not free
+gold(X1,Y1)[source(A)]
: A \== self & .my_name(Me)
<- .send(leader,tell,bid(gold(X1,Y1),10000,Me)).
// gold allocated to me
@palloc1[atomic]
+allocated(Gold,Ag)[source(leader)]
: .my_name(Ag) & free // I am still free
<- -free;
.print("Gold ",Gold," allocated to ",Ag);
!init_handle(Gold).
// some gold was allocated to me, but I can not
// handle it anymore, re-announce
@palloc2[atomic]
+allocated(Gold,Ag)[source(leader)]
: .my_name(Ag) & not free // I am no longer free
<- .print("I can not handle ",Gold," anymore!");
.print("(Re)announcing ",Gold," to others");
.broadcast(tell,Gold).
// someone else picked up the gold I am going to go,
// so drops the intention and chose another gold
@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_gold.
// someone else picked up a gold I know about,
// remove from my belief base
+picked(gold(X,Y))
<- -gold(X,Y)[source(_)].
@pih1[atomic]
+!init_handle(Gold)
: .desire(around(_,_))
<- .print("Dropping around(_,_) desires and intentions to handle ",Gold);
.drop_desire(around(_,_));
!init_handle(Gold).
@pih2[atomic]
+!init_handle(Gold)
: pos(X,Y)
<- .print("Going for ",Gold);
-+last_checked(X,Y);
!!handle(Gold). // must use !! to perform "handle" as not atomic
+!handle(gold(X,Y))
: not free
<- .print("Handling ",gold(X,Y)," now.");
.broadcast(tell, committed_to(gold(X,Y)));
!pos(X,Y);
!ensure(pick,gold(X,Y));
// broadcast that I got the gold(X,Y), to avoid someone
// else to pursue this gold
.broadcast(tell,picked(gold(X,Y)));
?depot(_,DX,DY);
!pos(DX,DY);
!ensure(drop, 0);
-gold(X,Y)[source(_)];
.print("Finish handling ",gold(X,Y));
!!choose_gold.
// if ensure(pick/drop) failed, pursue another gold
-!handle(G) : G
<- .print("failed to catch gold ",G);
.abolish(G); // ignore source
!!choose_gold.
-!handle(G) : true
<- .print("failed to handle ",G,", it isn't in the BB anyway");
!!choose_gold.
// no known gold to choose from
// become free again to search for gold
+!choose_gold
: not gold(_,_)
<- -+free.
// Finished one gold, but others left
// find the closest gold among the known options,
// that nobody else committed to
+!choose_gold
: gold(_,_)
<- .findall(gold(X,Y),gold(X,Y),LG);
!calc_gold_distance(LG,LD);
.length(LD,LLD); LLD > 0;
.print("Uncommitted gold distances: ",LD,LLD);
.min(LD,d(_,NewG));
.print("Next gold is ",NewG);
!!handle(NewG).
-!choose_gold <- -+free.
+!calc_gold_distance([],[]).
+!calc_gold_distance([gold(GX,GY)|R],[d(D,gold(GX,GY))|RD])
: pos(IX,IY) & not committed_to(gold(GX,GY))
<- operator.dist(IX,IY,GX,GY,D);
!calc_gold_distance(R,RD).
+!calc_gold_distance([_|R],RD)
<- !calc_gold_distance(R,RD).
// BCG!
// !pos is used when it is algways possible to go
// so this plans should not be used: +!pos(X,Y) : last_dir(skip) <-
// .print("It is not possible to go to ",X,"x",Y).
// in the future
//+last_dir(skip) <- .drop_goal(pos)
+!pos(X,Y) : pos(X,Y) <- .print("I've reached ",X,"x",Y).
+!pos(X,Y) : not pos(X,Y)
<- !next_step(X,Y);
!pos(X,Y).
+!ensure(pick,_) : pos(X,Y) & cell(X,Y,gold)
<- do(pick); ?carrying_gold.
// fail if no gold there or not carrying_gold after pick!
// handle(G) will "catch" this failure.
+!ensure(drop, _) : pos(X,Y) & depot(_,X,Y)
<- do(drop). //TODO: not ?carrying_gold.
/* Finding victims */
+cell(X,Y,victim,V): true
<- .print("Found vimctim",V);
.send(V,tell,stayHere(X,Y)).

View file

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

View file

@ -1,5 +1,6 @@
package operator;
import common.Constants;
import jason.asSyntax.*;
import jason.environment.Environment;
import jason.environment.grid.Location;
@ -52,20 +53,12 @@ public class WorldEnvironment extends Environment {
}
private void updateAgetPos(int i) {
String prefix = "";
if (i < 4)
prefix = "victim";
else if (i < 6) {
prefix = "searchDrone";
}
int offset = 0;
if (i > 3 && i < 6) {
offset = 4;
}
clearPercepts(prefix + (i + 1));
String agentName = getNameFromId(i);
System.out.println(agentName);
clearPercepts(agentName);
Location l = model.getAgPos(i);
addPercept(prefix + (i + 1 - offset), Literal.parseLiteral("pos(" + l.x + "," + l.y + ")"));
addPercept(agentName, Literal.parseLiteral("pos(" + l.x + "," + l.y + ")"));
}
private void updateAgPercept(int ag) {
@ -76,12 +69,13 @@ public class WorldEnvironment extends Environment {
clearPercepts(agName);
// its location
Location l = model.getAgPos(ag);
addPercept(agName, Literal.parseLiteral("pos(" + l.x + "," + l.y + ")"));
updateAgPercept(agName, l.x - 1, l.y - 1);
updateAgPercept(agName, l.x - 1, l.y);
updateAgPercept(agName, l.x - 1, l.y + 1);
updateAgPercept(agName, l.x, l.y - 1);
updateAgPercept(agName, l.x, l.y);
//updateAgPercept(agName, l.x, l.y);
updateAgPercept(agName, l.x, l.y + 1);
updateAgPercept(agName, l.x + 1, l.y - 1);
updateAgPercept(agName, l.x + 1, l.y);
@ -100,7 +94,15 @@ public class WorldEnvironment extends Environment {
addPercept(agName, Literal.parseLiteral("cell(" + x + "," + y + ",enemy)"));
}
if (model.hasObject(WorldModel.AGENT, x, y)) {
addPercept(agName, Literal.parseLiteral("cell(" + x + "," + y + ",ally)"));
if(agName.startsWith("searchDrone")) {
for (int i = 0; i < Constants.victimCount; i++) {
Location victimLocation = model.getAgPos(i);
if(victimLocation.x == x && victimLocation.y == y){
addPercept(agName, Literal.parseLiteral("cell(" + x + "," + y + ",victim,victim"+(i+1)+")"));
}
}
addPercept(agName, Literal.parseLiteral("cell(" + x + "," + y + ",ally)"));
}
}
}
}
@ -159,16 +161,16 @@ public class WorldEnvironment extends Environment {
return i;
}
if (agName.startsWith("searchDrone")) {
return i + 4;
return i + Constants.victimCount;
}
return -1;
}
public String getNameFromId(int i) {
if(i < 4) {
if(i < Constants.victimCount) {
return "victim"+(i+1);
} else if (i < 6) {
return "searchDrone"+(i+5);
} else if (i < Constants.victimCount+Constants.searchDroneCount) {
return "searchDrone"+(i-(Constants.victimCount-1));
}
return "";
}

View file

@ -27,25 +27,23 @@ public class get_direction extends DefaultInternalAction {
if (model.inGrid(to_x,to_y)) {
Location agnet_location = new Location(agent_x, agent_y);
while (!model.isFreeOfObstacle(to_x,to_y) && to_x > 0) to_x--;
while (!model.isFreeOfObstacle(to_x,to_y) && to_x < model.getWidth()) to_x++;
while (!model.isFreeOfObstacle(to_x,to_y) && to_y > 0) to_y--;
while (!model.isFreeOfObstacle(to_x,to_y) && to_y < model.getHeight()) to_y++;
while (!model.isFree(to_x,to_y) && to_x > 0) to_x--;
while (!model.isFree(to_x,to_y) && to_x < model.getWidth()) to_x++;
while (!model.isFree(to_x,to_y) && to_y > 0) to_y--;
while (!model.isFree(to_x,to_y) && to_y < model.getHeight()) to_y++;
System.out.println("To: "+to_x+", "+to_y+"\t"+agent_x+", "+agent_y);
if(to_x < agent_x && model.isFreeOfObstacle(agent_x-1,agent_y)){
if(to_x < agent_x && model.isFree(agent_x-1,agent_y)){
sAction = "left";
}else if (to_x > agent_x && model.isFreeOfObstacle(agent_x+1,agent_y)){
}else if (to_x > agent_x && model.isFree(agent_x+1,agent_y)){
sAction = "right";
}
if (to_y < agent_y && model.isFreeOfObstacle(agent_x,agent_y-1)){
sAction = "up";
} else if (to_y > agent_y && model.isFreeOfObstacle(agent_x,agent_y+1)) {
if (to_y > agent_y && model.isFree(agent_x,agent_y+1)) {
sAction = "down";
} else if (to_y < agent_y && model.isFree(agent_x,agent_y-1)){
sAction = "up";
}
}
System.out.println(sAction);
return un.unifies(terms[4], new Atom(sAction));
} catch (Throwable e) {
e.printStackTrace();

View file

@ -16,23 +16,24 @@ import java.util.Random;
public class get_direction extends DefaultInternalAction {
Random r = new Random();
static int skip = 0;
@Override
public Object execute(TransitionSystem ts, Unifier un, Term[] terms) throws Exception {
try {
String sAction = "skip";
if (skip++ % 5 == 0)
return un.unifies(terms[2], new Atom(sAction));
WorldModel model = WorldModel.get();
int AgX = (int)((NumberTerm)terms[0]).solve();
int AgY = (int)((NumberTerm)terms[1]).solve();
List<String> actions = new ArrayList<>();
if(AgX < 34)
if(AgX < model.getWidth()-1)
actions.add("right");
if(AgX > 0)
actions.add("left");
if(AgY < 34)
if(AgY < model.getHeight()-1)
actions.add("down");
if(AgY >= 0)
actions.add("up");

View file

@ -2,7 +2,7 @@
/* Initial beliefs and rules */
free.
life(500).
life(10).
/* Initial goals */
+gsize(_,_) : true
@ -13,10 +13,14 @@ life(500).
<- .wait("+pos(X,Y)", 500); // wait for it and try again
!!send_init_pos(S).
+free : pos(AgX,AgY) & life(L) > 0
+free : pos(AgX,AgY) & life(L) > 0 & not saved
<-
victim.get_direction(AgX, AgY, D);
do(D);
-+life(L-1);
.wait("",500);
//-+life(L-1);
-+free.
+stayHere(X,Y): free
<- .print("I will be saved!");
+saved;
-free.