diff --git a/src/main/scala/scim/components/Simulation.scala b/src/main/scala/scim/components/Simulation.scala index 5db1163..56f1a5f 100644 --- a/src/main/scala/scim/components/Simulation.scala +++ b/src/main/scala/scim/components/Simulation.scala @@ -31,7 +31,8 @@ class Simulation(config: Configuration) { def simCell(input: (Cell, Map[Group, List[(Group, Sensor, Option[GroundTruth])]])): Unit ={ val cell = input._1 val groups = input._2 - simGroups(time, cell, groups, prevTruths(cell), resultTruths(cell), sensorResults(cell)) + val configTruth = if(sharedMemory.groundTruthConfig.contains(time)) Some(sharedMemory.groundTruthConfig(time)) else None + simGroups(time, cell, groups, configTruth, prevTruths(cell), resultTruths(cell), sensorResults(cell)) } if(sharedConfig.parCell != 0 && cells.size >= sharedConfig.parCell ) { val cellList = cells.par @@ -44,7 +45,7 @@ class Simulation(config: Configuration) { output(time.time).broadcast(true) } - private def simGroups(time: Time, cell: Cell, groups: Map[Group, List[(Group, Sensor, Option[GroundTruth])]], prevTruths: Map[Group, Truth], resultTruths: Map[Group, Truth], resultSensors: Map[Group, Vector[SensorResult]]): Unit = { + private def simGroups(time: Time, cell: Cell, groups: Map[Group, List[(Group, Sensor, Option[GroundTruth])]], configTruths: Option[Map[Group, Truth]], PrevTruths: Map[Group, Truth], resultTruths: Map[Group, Truth], resultSensors: Map[Group, Vector[SensorResult]]): Unit = { // TODO: possible optimisation (see text below) // this can be further optimised as a child is only dependent on its parents ground truth and could run // at the same time as the parent in a different thread. This would allow the child to start running as soon @@ -57,7 +58,9 @@ class Simulation(config: Configuration) { val group = input._1 val truthGroup = group.getParentOrGroup // make sure the correct ground truth gets passed val groupList = input._2 - groupList.foreach(element => simulate(time, cell, prevTruths(truthGroup), resultTruths(group), resultSensors(group), element)) + // overwrite truth with value from configuration if set for this time and group + val prevTruth = if(!configTruths.isEmpty && configTruths.get.contains(truthGroup)) configTruths.get(truthGroup) else PrevTruths(truthGroup) + groupList.foreach(element => simulate(time, cell, prevTruth, resultTruths(group), resultSensors(group), element)) } if(sharedConfig.parGroup != 0 && cells.size >= sharedConfig.parGroup ) { val groupList = groups.par diff --git a/src/main/scala/scim/datastruct/Configuration.scala b/src/main/scala/scim/datastruct/Configuration.scala index fc7d72e..111423a 100644 --- a/src/main/scala/scim/datastruct/Configuration.scala +++ b/src/main/scala/scim/datastruct/Configuration.scala @@ -26,6 +26,7 @@ case class Time(time: Int, duration: Int) extends Ordered[Time]{ // Map[Time, Map[Cell, Map[Group, List(Group, Truth)]]] and getting the result for the sensor case class SharedMemory(sensor: Map[Time, Map[Cell, Map[Group, Vector[SensorResult]]]], groundTruth: Map[Time, Map[Cell, Map[Group, Truth]]], + groundTruthConfig: Map[Time, Map[Group, Truth]], config: SimulationConfig, output: Vector[BroadcastObject[Boolean]]) { // memory optimization: remove sensor and throw output into output @@ -157,6 +158,7 @@ case class GroundTruth(group: Group, behaviour: Option[Behaviour]) { case class Sensor(group: Group, cell: Cell, count: SensorCount, behaviour: Behaviour, parSensor: Int, sensorThreadPool: ForkJoinTaskSupport) { def simulate(time: Time, truth: Truth, results: Vector[SensorResult]): Unit = { + if(count.count == 0) return // allows for dummy sensors in dependency chains if(parSensor != 0 && parSensor <= count.count) { val sensorList = count.getVector.par sensorList.tasksupport = sensorThreadPool @@ -175,6 +177,13 @@ case class SensorCount(count: Int) { def getVector: Vector[Int] = { Vector.tabulate(count)(e => e) } + def add(otherCount: SensorCount): SensorCount = { + SensorCount(count + otherCount.count) + } + def add(otherCount: Int): SensorCount = { + SensorCount(count + otherCount) + } + } // NOTE: The Group is actually obsolete in the Tuple3 as Sensor and GroundTruth hold theirs (unless removed from their case class)