All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lib.CrowdEstimationLib.scala Maven / Gradle / Ivy

/*
 * Copyright (C) 2016-2017, Roberto Casadei, Mirko Viroli, and contributors.
 * See the LICENCE.txt file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
*/

package lib

import it.unibo.scafi.incarnations.BasicSimulationIncarnation._
import sims.SensorDefinitions

trait CrowdEstimationLib extends BuildingBlocks { self: AggregateProgram with SensorDefinitions =>
  /***********************************/
  /* IEEE Computer: Crowd estimation */
  /***********************************/

  val (high,low,none) = (2,1,0) // crowd level
  def managementRegions(grain: Double, metric: => Double): Boolean =
    S(grain, metric) /*{
    breakUsingUids(randomUid, grain, metric)
  }*/

  def unionHoodPlus[A](expr: => A): List[A] =
    foldhoodPlus(List[A]())(_++_){ List[A](expr) }

  def densityEst(p: Double, range: Double): Double = {
    val nearby = unionHoodPlus(
      mux (nbrRange < range) { nbr(List(mid())) } { List() }
    )

    val footprint = 1 /*if(self.hasEnvironmentVariable("footprint")) {
      self.getEnvironmentVariable("footprint") } else { 1 }*/
    nearby.size / p / (Math.PI * Math.pow(range,2) * footprint)
  }

  def rtSub(started: Boolean, state: Boolean, memoryTime: Double): Boolean = {
    if(state) {
      true
    } else {
      limitedMemory[Boolean,Double](started, false, memoryTime)._1
    }
  }

  def recentTrue(state: Boolean, memoryTime: Double): Boolean = {
    rtSub(timer(10) == 0, state, memoryTime)
  }

  def dangerousDensity(p: Double, r: Double) = {
    val mr = managementRegions(r*2, nbrRange)
    val danger = average(mr, densityEst(p, r)) > 2.17 &&
      summarize(mr, (_:Double)+(_:Double), 1 / p, 0) > 300
    if(danger) { high } else { low }
  }

  def crowdTracking(p: Double, r: Double, t: Double) = {
    val crowdRgn = recentTrue(densityEst(p, r)>1.08, t)
    if(crowdRgn) { dangerousDensity(p, r) } else { none }
  }

  /**
    *
    * @param p estimates the proportion of people with a device running the app
    * @param r is the range in which the neighbours are counted
    * @param warn estimates fraction of walkable space in the local urban env
    * @param t is the memory time
    * @return a boolean indicating whether there is warning or not.
    */
  def crowdWarning(p: Double, r: Double, warn: Double, t: Double): Boolean = {
    distanceTo(crowdTracking(p,r,t) == high) < warn
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy