[add] added initial configuration wiki entry
This commit is contained in:
185
docs/wiki/config/config.md
Normal file
185
docs/wiki/config/config.md
Normal file
@@ -0,0 +1,185 @@
|
||||
# Configuration File
|
||||
|
||||
## Simulation
|
||||
|
||||
* `duration`:`int` - number of simulation ticks, after which everything will be reset to the initial configuration
|
||||
* `tickfactor`:`int` - used to artificially add ticks by repeating the result of a simulation tick by the given value
|
||||
* `loop`:`bool` - loop the simulation
|
||||
* `loopcount`:`int` - amount of loops, `0` for infinite
|
||||
|
||||
## Sensors
|
||||
|
||||
Elements:
|
||||
|
||||
* `group`:`String` - used to assign ground truth and behaviour to the sensors. Any String can be used, internally assigned an `int`, by adding all groups to an array and using their index
|
||||
* `cells`:`array` _[optional]_ - holds the x-/y-coordinates and count of the sensors in the group, only optional if `blocks` is present
|
||||
* `x`:`int` - x-coordinate
|
||||
* `y`:`int` - y-coordinate
|
||||
* `count`:`int` - count of the sensors in this cell
|
||||
Alternative condensed notation as `array`: `[x, y, count]`
|
||||
* `blocks`:`array` _[optional]_ - holds start-/end-coordinates and count of sensors in the group, only optional if `cells` is present
|
||||
* `start`:`[int, int]` - start coordinates `[x, y]` of a block
|
||||
* `end`:`[int, int]` - end coordinates `[x, y]` of a block, can be equal to `start` (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 assignment
|
||||
* `parent`:`String` _[optional]_ - parent group assignment. The parents group ground truth for the current simulation tick is calculated before this grout and passed to it
|
||||
* `value`:`double` - ground truth value
|
||||
* `timeline`:`array` - sets simulation tick when this ground truth is active and turns inactive.
|
||||
* `start`:`int` - simulation tick when this function is active
|
||||
* `end`:`int` _[optional]_ - last simulation tick before this function is inactive
|
||||
Alternative condensed of `timeline` notation as `array`: `[start, end]`
|
||||
Alternative condensed of `value` notation as `array`: `[start, value or None, ...]`
|
||||
* `delta`:`array` _[optional]_ - function to calculate `value` of the next simulation tick, only called if no value is defined for the next tick. Result is saved as new `value` and passed again to the function for the next tick. If no function is given, the `value` remains
|
||||
* `name`:`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 the `value`
|
||||
* `timeline`:`array` - sets simulation tick when this function is active and turns inactive.
|
||||
* `start`:`int` - simulation tick when this function is active
|
||||
* `end`:`int` _[optional]_ - last simulation tick before this function is inactive
|
||||
Alternative condensed of `timeline` notation as `array`: `[start, end]`
|
||||
Alternative condensed of `delta` notation as `array`: `[start, name or None, [args] or []]`
|
||||
* `cells`:`array` _[optional]_ - holds the x-/y-coordinates and count of assigned sensors in the group, only optional if `blocks` is present
|
||||
* `x`:`int` - x-coordinate
|
||||
* `y`:`int` - y-coordinate
|
||||
* `count`:`int` _[optional]_ - count of assigned sensors in this cell, only optional if `percent` is present
|
||||
* `percent`:`double` _[optional]_ - percent of assigned sensors (rounded) in this cell, only optional if `count` is present
|
||||
Alternative condensed notation as `array`: `[x, y, count]`
|
||||
* `blocks`:`array` _[optional]_ - holds start-/end-coordinates and count of assigned sensors in the group, only optional if `cells` is present
|
||||
* `start`:`[int, int]` - start coordinates `[x, y]` of a block
|
||||
* `end`:`[int, int]` - end coordinates `[x, y]` of a block, can be equal to `start` (but not desirable)
|
||||
* `count`:`int` _[optional]_ - count of assigned sensors in this block, only optional if `percent` is present
|
||||
* `percent`:`double` _[optional]_ - percent of assigned sensors (rounded) in this block, only optional if `count` is 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 assignment
|
||||
* `sharedObject`:`String` _[optional]_ _[experimental idea]_ - an object shared between sensor `behaviours`, 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 receives `ground truth` which can be `None`. Function returns `double` or `None`. If no function is given, `None` is returned as result for the tick
|
||||
* `name`:`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 the `value`
|
||||
* `timeline`:`array` - sets simulation tick when this function is active and turns inactive.
|
||||
* `start`:`int` - simulation tick when this function is active
|
||||
* `end`:`int` _[optional]_ - last simulation tick before this function is inactive
|
||||
Alternative condensed of `timeline` notation as `array`: `[start, end]`
|
||||
Alternative condensed of `functions` notation as `array`: `[start, name or None, [args] or []]`
|
||||
* `cells`:`array` _[optional]_ - holds the x-/y-coordinates and count of assigned sensors in the group, only optional if `blocks` is present
|
||||
* `x`:`int` - x-coordinate
|
||||
* `y`:`int` - y-coordinate
|
||||
* `count`:`int` _[optional]_ - count of assigned sensors in this cell, only optional if `percent` is present
|
||||
* `percent`:`double` _[optional]_ - percent of assigned sensors (rounded) in this cell, only optional if `count` is present
|
||||
Alternative condensed notation as `array`: `[x, y, count]`
|
||||
* `blocks`:`array` _[optional]_ - holds start-/end-coordinates and count of assigned sensors in the group, only optional if `cells` is present
|
||||
* `start`:`[int, int]` - start coordinates `[x, y]` of a block
|
||||
* `end`:`[int, int]` - end coordinates `[x, y]` of a block, can be equal to `start` (but not desirable)
|
||||
* `count`:`int` _[optional]_ - count of assigned sensors in this block, only optional if `percent` is present
|
||||
* `percent`:`double` _[optional]_ - percent of assigned sensors (rounded) in this block, only optional if `count` is 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 `None` from a sensor `behaviour` is treated as if the sensor did not output any data
|
||||
* as `group` entries are not _[unique]_ it is possible to have multiple definitions of the same `group`. 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 `delta` function that just returns the parent `ground 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:
|
||||
```yml
|
||||
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 `behaviour`of the sensor. This default would have to be added to `sensor`.
|
||||
|
||||
### adding a sensor block from config
|
||||
|
||||
1. get the smallest `x` and `y` from `start` and `end` from a `blocks` element, save as `bottomleft`
|
||||
2. save other `x` and `y` as `topright`
|
||||
3. calculate the amount of cells in the block by multiplying the distance of the `x` and `y` pairs:
|
||||
```scala
|
||||
// no abs() necessary as topright is always greater than or equal to topleft
|
||||
cellCount = (topright.x - bottomleft.x + 1) * (topright.x - bottomleft.x + 1)
|
||||
```
|
||||
4. set amount of sensors per cell in `sensorsPerCell`
|
||||
```pseudo
|
||||
if cellCount < count:
|
||||
sensorsPerCell = roundDown(count/cellCount)
|
||||
extraSensors = count - (sensorsPerCell*cellCount)
|
||||
else:
|
||||
sensorsPerCell = 1
|
||||
```
|
||||
|
||||
```scala
|
||||
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)
|
||||
|
||||
70
docs/wiki/config/config.yml
Normal file
70
docs/wiki/config/config.yml
Normal file
@@ -0,0 +1,70 @@
|
||||
simulation:
|
||||
duration: 500
|
||||
tickfactor: 10
|
||||
loop: true
|
||||
loopcount: 20
|
||||
|
||||
sensors:
|
||||
- group: temperature
|
||||
cells:
|
||||
- x: 0
|
||||
y: 2
|
||||
count: 10
|
||||
- [2, 3, 50]
|
||||
blocks:
|
||||
- start: [8, 1]
|
||||
end: [3, 3]
|
||||
count: 30
|
||||
|
||||
groundtruth:
|
||||
- group: temperature
|
||||
truth:
|
||||
- value: 11
|
||||
timeline:
|
||||
- start: 0
|
||||
end: 120
|
||||
- [240, 360]
|
||||
delta:
|
||||
- name: factor
|
||||
args:
|
||||
- 1.1
|
||||
timeline:
|
||||
- start: 60
|
||||
end: 120
|
||||
cells:
|
||||
- [0, 2, 10]
|
||||
blocks:
|
||||
- start: [8, 1]
|
||||
end: [3, 3]
|
||||
count: 50
|
||||
- group: humidity
|
||||
parent: temperature
|
||||
truth:
|
||||
- [0, None]
|
||||
- [30, 0.6]
|
||||
- [50, None]
|
||||
delta:
|
||||
- [10, None, []]
|
||||
- [30, addValuePercent, [0.03, 0.8]]
|
||||
- [50, humidFromTemp, []]
|
||||
blocks:
|
||||
- start: [15, 15]
|
||||
end: [17, 17]
|
||||
percent: 0.8
|
||||
|
||||
behaviour:
|
||||
- group: temperature
|
||||
sharedObject: objectTemp
|
||||
functions:
|
||||
- name: randomValue
|
||||
args:
|
||||
- 40
|
||||
- 80
|
||||
duration:
|
||||
- start: 60
|
||||
- [100, normalValue, [2]]
|
||||
- [120, None, []]
|
||||
blocks:
|
||||
- start: [5,6]
|
||||
end: [8,9]
|
||||
percent: 1.0
|
||||
Reference in New Issue
Block a user