//*************************************************************** // Copyright 2008 Centre For Advanced Spatial Analysis, UCL // // Author: Joel Dearden, University College London // // Contact: j.dearden@ucl.ac.uk // // Joel Dearden, // Centre for Advanced Spatial Analysis, // University College London, // 1-19 Torrington Place, // London, // WC1E 7HB // // // This file is part of SLPedEvac. // // SLPedEvac is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // SLPedEvac is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with SLPedEvac. If not, see . // //*************************************************************** //CONSTANTS START========================================= string controllerName = "ABMcontroller"; integer controllerSendChannel = -220211; integer controllerReceiveChannel = -293321; string tickMsg = "TiCk"; string pedInMsg = "pEdiN"; string pedOutMsg = "pedOUt"; integer rayChannel = -1; integer rayChannelBase = 1000000; integer rayChannelStep = 2; //band size usable by each pedestrian integer talkToBuilder = -9292921; integer talkToStrobeLight = -2928333; integer talkToDisplay = -9000; integer talkToBuildingComponents = -8927211; float interval = 4; //seconds integer totalModelSeconds = 0; //CONSTANTS END========================================= //VARIABLES START========================================= integer totalPedestrians = 0; integer rayChannelGenerator = 0; integer doingUpdate = FALSE; integer totalPedestriansDoingUpdate = 0; integer totalPedestriansCompletedUpdate = 0; integer buildingReady = FALSE; //VARIABLES END========================================= //FUNCTIONS START========================================= startUpdate() { llOwnerSay("startUpdate"); //cancel timer event llSetTimerEvent(0); doingUpdate = TRUE; totalPedestriansDoingUpdate = totalPedestrians; totalPedestriansCompletedUpdate = 0; //broadcast clock message llShout(controllerSendChannel, tickMsg); } checkUpdateStatus() { llOwnerSay("checkStatusUpdate"); llOwnerSay("totalPedestriansDoingUpdate:" + (string)totalPedestriansDoingUpdate); llOwnerSay("totalPedestriansCompletedUpdate:" + (string)totalPedestriansCompletedUpdate); if(totalPedestriansCompletedUpdate >= totalPedestriansDoingUpdate) { llOwnerSay("completed update"); //send "register model second" HTTP message llHTTPRequest("
/input.aspx?f=rms", [], ""); llOwnerSay("registering model second"); totalModelSeconds++; llSetText("TOTAL MODEL SECONDS: " + (string)totalModelSeconds + "s", <1,1,1>, 1.0); llSay(talkToDisplay, "TIME: " + (string)totalModelSeconds + "S"); doingUpdate = FALSE; //reset timer event //llSetTimerEvent(interval); //wait a second before we start the next update to allow pedestrians time to process ACK and change state llSleep(1.0); startUpdate(); } } reset() { buildingReady = FALSE; llOwnerSay("reset"); llSetText("", <1,1,1>, 1.0); llSay(talkToBuilder, "clear_site"); totalPedestrians = 0; rayChannelGenerator = 0; totalModelSeconds = 0; doingUpdate = FALSE; totalPedestriansDoingUpdate = 0; totalPedestriansCompletedUpdate = 0; //send reset HTTP message llOwnerSay("resetting model."); llHTTPRequest("
/input.aspx?f=r", [], ""); //give server time to reset... llOwnerSay("giving server time to reset"); llSetTimerEvent(5); } load_simple_layout() { reset(); llSleep(2.0); llSay(talkToBuilder, "build_simple"); } load_complicated_layout() { reset(); llSleep(2.0); llSay(talkToBuilder, "build_complicated"); } load_multifloor_layout() { reset(); llSleep(2.0); llSay(talkToBuilder, "build_multifloor"); } //FUNCTIONS END========================================= default { state_entry() { llOwnerSay("default state entry"); llSetText("", <1,1,1>, 1.0); state waiting; } } state waiting { state_entry() { llSay(talkToDisplay, " NO ALARM "); llOwnerSay("waiting state entry"); llSay(talkToStrobeLight, "off"); llListen(controllerReceiveChannel, "", NULL_KEY, ""); } listen(integer channel, string name, key id, string message) { if(channel == controllerReceiveChannel) { if(message == "builder_finished") { buildingReady = TRUE; //register components with webserver llSay(talkToBuildingComponents, "REG"); } if(message == "fire_alarm") { if(buildingReady) { //fire alarm sounded //tell all agents llShout(controllerSendChannel, "alarm"); //give time for all agents to finish wandering and hear the alarm llSleep(10.0); //start updating agents one second at a time state alarm_active; } else { llSay(0, "building not ready"); } } if(message == "reset") { //reset model reset(); } if(message == "simple_layout") { load_simple_layout(); } if(message == "complicated_layout") { load_complicated_layout(); } if(message == "multifloor_layout") { load_multifloor_layout(); } if(message == pedInMsg) { llOwnerSay("PED_IN"); totalPedestrians++; //send pedestrian its ray channel llShout(controllerSendChannel, (string)id + ":" + (string)(rayChannelBase + rayChannelGenerator)); rayChannelGenerator += rayChannelStep; return; } } } } state alarm_active { state_entry() { llOwnerSay("alarm active state entry"); llSay(talkToDisplay, " ALARM ON "); llSay(talkToStrobeLight, "on"); llListen(controllerReceiveChannel, "", NULL_KEY, ""); llSetTimerEvent(interval); } listen(integer channel, string name, key id, string message) { if(channel == controllerReceiveChannel) { if(message == "reset") { reset(); state waiting; } if(doingUpdate) { if(message == pedOutMsg) { llOwnerSay("PED_OUT_DURING_UPDATE"); totalPedestrians--; //treat this as equivalent to registering a move (just out of the model) totalPedestriansCompletedUpdate++; checkUpdateStatus(); return; } if(message == "RegMoV") { llOwnerSay("got regmove"); llSay(controllerSendChannel, "ACK" + (string)id); totalPedestriansCompletedUpdate++; checkUpdateStatus(); return; } } else { //not doing update if(message == pedOutMsg) { llOwnerSay("PED_OUT"); totalPedestrians--; return; } } } } timer() { //don't start updating until we have at least one pedestrian registered if(totalPedestrians > 0) { startUpdate(); } else { llOwnerSay("waiting for pedestrians..."); } } }