{ name:'My Simulation World', classes : { node: { behaviour:open('node.js'), visual:{ shape:'circle', width:10, height:10, x:0,y:0, fill: { color:'red', opacity: 0.5 } } }, world : { behaviour:open('world.js'), visual:{ shape:'circle', width:50, height:50, center:{x:0,y:0}, fill: { color:'green', opacity: 0.0 } } } }, // Simulation parameter that can be changed by run-time configuration parameter : { ip1:'localhost', ipport1:10002, }, world : { init: { // Initial agent creation on each node agents: { node:function (nodeId,position,parameter) { // Create on each node a node agent, return respective // agent parameters! If no agent should be created on the // respective node, undefined must be returned! // level 3: agents with full access to simulation world // parameter is either {} or given by world.nodes .parameter (see below) if (nodeId.indexOf('beacon')==0 || nodeId.indexOf('mobile')==0) return {level:3,args:[{x:position.x,y:position.y,parameter:parameter}]} }, world: function(nodeId) { if (nodeId=='world') return {level:3,args:[{}]}; } } }, // Create nodes nodes: function () { function makeNode(x,y,id) { var phy; if (id=='mobile device 1') r=80; else r=200; return { id:id, x:x, y:y, // node/agent parameter object for agent initialization (agent class node, see world.init.agents.node) // is stored in node.options.parameter, too parameter : { mysecret:(Math.random()*1000000)|0, dir : Aios.DIR.NORTH, }, // create virtual communication ports ports: { wlan : { type:'multicast', status: function (nodes) { // Filter out nodes, e.g., beacons only? return nodes; }, visual: { shape:'circle', width: r, height: r, line: { color: 'grey' } } }, phy : phy }, visual : { shape:'rect', width:30, height:30, fill: { color:'green', opacity: 0.5 } } } } function makeBeacon(x,y,id) { var phy; if (id == 'beacon 1') // Physical connection to outside of simulation (another JAM node) phy={type:'physical', ip:'*', to:model.parameter.ip1+':'+model.parameter.ipport1, proto:'udp'}; return { id:id, x:x, y:y, ports: { wlan : { type:'multicast', status: function (nodes) { // Filter out nodes, e.g., beacons only? return nodes; }, visual: { shape:'circle', width: 80, height: 80, line: { color: 'grey' } } }, phy:phy }, visual : { shape:'triangle', width:50, height:50, fill: { color:'yellow', opacity: 0.5 } } } } function makeWorld(x,y) { return { id:'world', x:x, y:y, visual : { shape:'icon', icon:'world', label:{ text:'World', fontSize:20 }, width:50, height:50, fill: { color:'black', opacity: 0.5 }, line:{ width:1, } } } } function onstreet() { // 1. Select one street segment x,y,w,h, var x,y,s=Math.random(),r; if (s < 0.3) r=[10,10,1000,100]; else if (s < 0.6) r=[450,110,100,500]; else r=[10,610,1000,100]; // 2. Select x/y position in segment x=r[0]+Math.random()*r[2]; y=r[1]+Math.random()*r[3]; return {x:x,y:y} } var more=[]; // Create much more mobile devices on the streets ... for(var i=3;i<50;i++) { var pos=onstreet(); more.push(makeNode(pos.x,pos.y,'mobile device '+i)) } // Create much more beacons on the streets ... for(var i=5;i<15;i++) { var pos=onstreet(); more.push(makeBeacon(pos.x,pos.y,'beacon '+i)) } return [ makeWorld(600,500), makeNode(50,50,'mobile device 1'), makeNode(70,140,'mobile device 2'), makeBeacon(120,140,'beacon 1'), makeBeacon(600,270,'beacon 2'), makeBeacon(410,370,'beacon 3'), makeBeacon(300,210,'beacon 4'), ].concat(more); }, // Auxiliary passive resources (buildings, streets) resources: function () { // Streets function makeArea(id,x,y,w,h,color) { return { id:id, visual: { shape:'rect', x:x, y:y, width:w, height:h, fill: { color: 'grey', opacity:0.1, }, line: { color: color||'blue', width:2 } } }; } return [ makeArea('Street 1',10,10,1000,100), makeArea('Street 2',450,110,100,500), makeArea('Street 3',10,610,1000,100), makeArea('Building 1',300,210,100,100,'red'), makeArea('Building 2',600,270,100,100,'red'), makeArea('Building 3',310,370,100,100,'red'), makeArea('Building 4',50,120,100,100,'red'), ] }, } }