Better search drone logic
This commit is contained in:
parent
923ae73b5e
commit
5657baac66
11 changed files with 58 additions and 213 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -17,8 +17,10 @@ MAS airSeaRescue {
|
|||
agents:
|
||||
victim#4;
|
||||
searchDrone#2;
|
||||
|
||||
rescueDrone#3;
|
||||
operator;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
180
searchDrone.asl
180
searchDrone.asl
|
@ -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)).
|
||||
|
||||
|
|
8
src/java/common/Constants.java
Normal file
8
src/java/common/Constants.java
Normal file
|
@ -0,0 +1,8 @@
|
|||
package common;
|
||||
|
||||
public class Constants {
|
||||
public static int victimCount = 4;
|
||||
public static int searchDroneCount = 2;
|
||||
|
||||
private Constants(){}
|
||||
}
|
|
@ -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 "";
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
|
|
12
victim.asl
12
victim.asl
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue