11 KiB
Configuration File
Simulation
duration:int- number of simulation ticks, after which everything will be reset to the initial configurationtickfactor:int- used to artificially add ticks by repeating the result of a simulation tick by the given valueloop:bool- loop the simulationloopcount:int- amount of loops,0for infinite
Sensors
Elements:
group:String- used to assign ground truth and behaviour to the sensors. Any String can be used, internally assigned anint, by adding all groups to an array and using their indexcells:array[optional] - holds the x-/y-coordinates and count of the sensors in the group, only optional ifblocksis presentx:int- x-coordinatey:int- y-coordinatecount:int- count of the sensors in this cell
Alternative condensed notation asarray:[x, y, count]
blocks:array[optional] - holds start-/end-coordinates and count of sensors in the group, only optional ifcellsis presentstart:[int, int]- start coordinates[x, y]of a blockend:[int, int]- end coordinates[x, y]of a block, can be equal tostart(but not desirable)count:int- count of the sensors in this block
Notes: Overlaps of cells and/or blocks within a group are possible (but not desirable). The result will be the sum of all count values.
The distribution in blocks goes from left to right (x-axis), bottom to top (y-axis):
Examples:
2x2 block with 3 sensors (labeled 1 to n):
| 3 | |
| 1 | 2 |
If the count of sensors is greater than the amount of cells in a block, they get evenly distributed with any leftovers being distributed like the example above:
2x2 block with 11 sensors (labeled 1 to n):
- amount of cells: 4
count: 11- evenly distributed: 2 per cell
- leftovers: 3 (marked with
())
| 7, 8, (9) | 10, 11 |
| 1, 2, (3) | 4, 5, (6) |
Ground Truth
Elements:
group:String- sensor group assignmentparent:String[optional] - parent group assignment. The parents group ground truth for the current simulation tick is calculated before this grout and passed to itvalue:double- ground truth valuetimeline:array- sets simulation tick when this ground truth is active and turns inactive.start:int- simulation tick when this function is activeend:int[optional] - last simulation tick before this function is inactive
Alternative condensed oftimelinenotation asarray:[start, end]Alternative condensed ofvaluenotation asarray:[start, value or None, ...]
delta:array[optional] - function to calculatevalueof the next simulation tick, only called if no value is defined for the next tick. Result is saved as newvalueand passed again to the function for the next tick. If no function is given, thevalueremainsname:String- name of the function. Needs to exist at compile time in a map:["name" -> (value: double, parentValue: double, args: ...) => double]args:array- arguments passed to the function in addition to thevaluetimeline:array- sets simulation tick when this function is active and turns inactive.start:int- simulation tick when this function is activeend:int[optional] - last simulation tick before this function is inactive Alternative condensed oftimelinenotation asarray:[start, end]
Alternative condensed ofdeltanotation asarray:[start, name or None, [args] or []]
cells:array[optional] - holds the x-/y-coordinates and count of assigned sensors in the group, only optional ifblocksis presentx:int- x-coordinatey:int- y-coordinatecount:int[optional] - count of assigned sensors in this cell, only optional ifpercentis presentpercent:double[optional] - percent of assigned sensors (rounded) in this cell, only optional ifcountis present Alternative condensed notation asarray:[x, y, count]
blocks:array[optional] - holds start-/end-coordinates and count of assigned sensors in the group, only optional ifcellsis presentstart:[int, int]- start coordinates[x, y]of a blockend:[int, int]- end coordinates[x, y]of a block, can be equal tostart(but not desirable)count:int[optional] - count of assigned sensors in this block, only optional ifpercentis presentpercent:double[optional] - percent of assigned sensors (rounded) in this block, only optional ifcountis present
Notes: Overlaps of cells and/or blocks within a group are possible (but not desirable). The result will be the sum of all count, percent values.
The distribution in blocks goes from left to right (x-axis), bottom to top (y-axis) (see above)
Behaviour
Elements:
group:String- sensor group assignmentsharedObject:String[optional] [experimental idea] - an object shared between sensorbehaviours, can be waited up and synchronized. Use case example: cascading failure of sensors of different groups.
More of an idea, as this might be complex to implement in an asynchronous environment.
functions:array[optional] - function to calculate the output of a sensor on a given simulation tick. Function receivesground truthwhich can beNone. Function returnsdoubleorNone. If no function is given,Noneis returned as result for the tickname:String- name of the function. Needs to exist at compile time in a map:["name" -> (groundTruth: double, args: ...) => double]args:array- arguments passed to the function in addition to thevaluetimeline:array- sets simulation tick when this function is active and turns inactive.start:int- simulation tick when this function is activeend:int[optional] - last simulation tick before this function is inactive Alternative condensed oftimelinenotation asarray:[start, end]
Alternative condensed offunctionsnotation asarray:[start, name or None, [args] or []]
cells:array[optional] - holds the x-/y-coordinates and count of assigned sensors in the group, only optional ifblocksis presentx:int- x-coordinatey:int- y-coordinatecount:int[optional] - count of assigned sensors in this cell, only optional ifpercentis presentpercent:double[optional] - percent of assigned sensors (rounded) in this cell, only optional ifcountis present Alternative condensed notation asarray:[x, y, count]
blocks:array[optional] - holds start-/end-coordinates and count of assigned sensors in the group, only optional ifcellsis presentstart:[int, int]- start coordinates[x, y]of a blockend:[int, int]- end coordinates[x, y]of a block, can be equal tostart(but not desirable)count:int[optional] - count of assigned sensors in this block, only optional ifpercentis presentpercent:double[optional] - percent of assigned sensors (rounded) in this block, only optional ifcountis present
Notes: Overlaps of cells and/or blocks within a group are possible (but not desirable). The result will be the sum of all count, percent values.
The distribution in blocks goes from left to right (x-axis), bottom to top (y-axis) (see above)
Implementation Ideas
general
- the result
Nonefrom a sensorbehaviouris treated as if the sensor did not output any data - as
groupentries are not [unique] it is possible to have multiple definitions of the samegroup. If any element of the group conflicts with another definition, the last declaration takes precedence - configuring failing sensors in a type of sensor can be achieved by creating two groups (working, failing), assigning the working group as parent of the failing und using a
deltafunction that just returns the parentground truth
storing function<->timeline relations
All timeline dependend elements (e.g. groundtruth, delta, behaviour) are held in an array of their respective group. The array is initialized with an Option[T] that is set to None. All elements get inserted with their corresponding timeline: start value and the None gets inserted with the timeline: end+1 value. A modified binary search (that will return either the value if found or the next lower value) is then used to get the element at any given simulation tick:
[0:None, 30:factor, 61:None, 120:factor] would correspond to:
delta:
- name: factor
args:
- 1.1
timeline:
- start: 30
end: 60
- start: 120
a lookup of delta at tick 20 would result in None, at tick 42 in factor, at tick 110 in None, anytime after 119 in factor.
For the groundtruth and behaviour a None results in no output of the effected sensors. A None in the delta would result in no change of the value, but normal sensor output.
Alternatively a None in behaviour could result in a default behaviourof the sensor. This default would have to be added to sensor.
adding a sensor block from config
- get the smallest
xandyfromstartandendfrom ablockselement, save asbottomleft - save other
xandyastopright - calculate the amount of cells in the block by multiplying the distance of the
xandypairs:
// no abs() necessary as topright is always greater than or equal to topleft
cellCount = (topright.x - bottomleft.x + 1) * (topright.x - bottomleft.x + 1)
- set amount of sensors per cell in
sensorsPerCell
if cellCount < count:
sensorsPerCell = roundDown(count/cellCount)
extraSensors = count - (sensorsPerCell*cellCount)
else:
sensorsPerCell = 1
for {
y <- bottomleft.y to topright.y
x <- bottomleft.x to topright.x
} {
// exit condition for count < cellCount
if (count <= 0) break else count -= 1
var sensors: Int = sensorsPerCell
if (extraSensors > 0)
{
sensors += 1
extraSensors -= 1
}
addSensors((x, y), sensors, ...)
}
TODO: Decide which structure to use: Array.ofDim vs Array(Array()) vs map
applying ground truth/behaviour to block
fast: uneven distribution, start left to right, top to bottom and grab all sensors in each cell until done assigning required sensors
slow: even distribution, iterate over block left to right, top to bottom and assign a single sensor (if available) in each cell, continue until done
(possible optimisation: get all counts of sensors per cell, sort by size, delete smallest and assign that count on all available cells, subtract from remaining counts, repeat until done)