jam/test/test-simu2.js

290 lines
7.2 KiB
JavaScript
Raw Normal View History

2024-08-27 00:15:55 +02:00
/*
SEJAM2 Demo: Vehicle agents on streets
1. Physical and computational agents
2. Netlog API und Patchworld
3. Resources (streets)
*/
function world() {
this.modelSim=null;
this.children=[];
this.streets=[];
this.act = {
init: function () {
var self=this, row , patches, i,j,s,st;
this.modelSim = simu.model();
this.streets=net.ask('resources-street','*');
patches = net.ask('patches','*');
for(s=0;s<this.streets.length;s++) {
st=this.streets[s];
for(j=st.y;j<st.y+st.h;j++)
for(i=st.x;i<st.x+st.w;i++)
patches[j][i].street=st.resource;
}
net.create('agent-vehicle',4,function (ag,index) {
var st=self.streets[0];
ag.street=st;
ag.dir=DIR.WEST;
net.turn(ag.dir);
net.setxy(st.x+int(st.w/2)-3+index,st.y)
})
},
wait: function () {},
end: function () {}
}
this.trans = {
init:wait,
}
this.next=init
}
function vehicle() {
this.group=null;
this.passenger=[];
this.dir=DIR.ORIGIN;
this.sensors={}
this.speed=0;
this.street=null;
this.todo={};
this.last=null;
this.act = {
init: function () {
},
percept: function () {
switch (this.dir) {
case DIR.WEST:
this.sensors.front = reverse(net.ask('patches',{dir:DIR.WEST,distance:4}))
this.sensors.left = net.ask('patches',{dir:DIR.SOUTH,distance:4})
this.sensors.right = reverse(net.ask('patches',{dir:DIR.NORTH,distance:4}))
break;
case DIR.EAST:
this.sensors.front = net.ask('patches',{dir:DIR.EAST,distance:4})
this.sensors.left = reverse(net.ask('patches',{dir:DIR.NORTH,distance:4}))
this.sensors.right = net.ask('patches',{dir:DIR.SOUTH,distance:4})
break;
case DIR.NORTH:
this.sensors.front = reverse(net.ask('patches',{dir:DIR.NORTH,distance:4}))
this.sensors.left = reverse(net.ask('patches',{dir:DIR.WEST,distance:4}))
this.sensors.right = net.ask('patches',{dir:DIR.EAST,distance:4})
break;
case DIR.SOUTH:
this.sensors.front = net.ask('patches',{dir:DIR.SOUTH,distance:4})
this.sensors.left = net.ask('patches',{dir:DIR.EAST,distance:4})
this.sensors.right = reverse(net.ask('patches',{dir:DIR.WEST,distance:4}))
break;
}
if (this.sensors.front[0].street != this.street.resource)
net.die(); // vehicle left the road!
log(simu.inspect(this.sensors.right))
if (this.sensors.right[1].street &&
this.sensors.right[1].street != this.street.resource &&
this.last != this.sensors.right[1].street) {
var next=net.ask('resource',this.sensors.right[1].street)
log(next.resource)
this.todo={right:next};
}
if (this.sensors.front[1].street &&
this.sensors.front[1].street != this.street.resource &&
this.last != this.sensors.front[1].street) {
var next=net.ask('resource',this.sensors.front[1].street)
log(next.resource)
this.todo={forward:1,right:next};
}
},
move: function () {
if (this.todo.forward) net.forward(this.todo.forward);
if (this.todo.right) {
// change street by right turn
this.last=this.street.resource;
this.street=this.todo.right;
net.turn(90);
switch (net.get('heading')) {
case 0: this.dir=DIR.NORTH; break;
case 90: this.dir=DIR.EAST; break;
case 180: this.dir=DIR.SOUTH; break;
case 270: this.dir=DIR.WEST; break;
}
}
if (!this.todo.forward) net.forward(1);
this.todo={}
},
wait: function () {
sleep(5)
},
end: function () {}
}
this.trans = {
init:percept,
percept:wait,
wait:move,
move:percept,
}
this.next=init
}
model = {
name:'Test Simulation',
// Agents behaviour and visuals
agents : {
world : {
behaviour:world,
visual:{
shape:'circle',
width:10,
height:10,
fill: {
color:'green',
opacity: 0.0
}
}
},
vehicle : {
behaviour : vehicle,
visual:{
shape:'circle',
width:4,
height:4,
fill: {
color:'white',
opacity: 0.0
}
},
type:'physical'
},
},
parameter : {
},
// Node constructor functions (visual)
nodes: {
world: function (x,y) {
return {
id:'world',
x:x, // patch position
y:y,
visual : {
shape:'icon',
icon:'world',
label:{
text:'World',
fontSize:14
},
width:20,
height:20,
fill: {
color:'black',
opacity: 0.5
}
},
}
},
vehicle : function (x,y,id) {
return {
id:id,
x:x, // patch position
y:y,
visual : {
shape :'rect',
width :10,
height:10,
fill: {
color:'black',
opacity: 0.5
},
line : {
width:1,
color:'black'
},
}
}
}
},
resources : {
street : function (id,x,y,w,h) {
return {
id:id,
class:'street',
visual: {
shape:'rect',
label:{
text:id,
fontSize:5
},
x:x,
y:y,
width:w,
height:h,
line: {
color: '#888',
width: 0
},
fill : {
color: '#888',
opacity: 0.2,
}
}
};
}
},
parameter : {
streets:{}
},
world : {
init: {
agents: {
world: function(nodeId) {
if (nodeId=='world')
return {level:3,args:{verbose:1}};
}
}
},
// special nodes
map : function (model) {
return [
model.nodes.world(20,20), // patch position
]
},
resources : function (model) {
// patch grid coordinates!!
var i,j,x,y;
// construct street map
var streets=[];
i=1;
for(y=3;y<model.world.patchgrid.rows-5;y+=7,i++) {
model.parameter.streets['street'+i] = [
2,y,(model.world.patchgrid.cols-4),3
]
i++;
if (y<model.world.patchgrid.rows-10)
for(x=3;x<model.world.patchgrid.cols-5;x+=10,i++) {
model.parameter.streets['street'+i] = [
x,(y+3),3,4
]
}
}
// construct
for(var p in model.parameter.streets) {
var coord = model.parameter.streets[p];
streets.push(model.resources.street(p,coord[0],coord[1],coord[2],coord[3]))
}
return streets;
},
patchgrid : {
rows : 20,
cols : 20,
width : 10, // geometrical width and height of patch in pixels
height : 10,
floating : true, // physical agents are tuples <logical node, physical agent>
}
}
}