• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Scala-Robotics-Simulator / PPS-22-srs / #408

27 Aug 2025 05:16PM UTC coverage: 45.534% (+0.5%) from 45.055%
#408

Pull #68

github

davidcohenDC
refactor(CreationDSL): remove customLightMap
Pull Request #68: perf(illumination): optimize and use ValidEnvironment in Illumination

161 of 201 new or added lines in 10 files covered. (80.1%)

3 existing lines in 2 files now uncovered.

1147 of 2519 relevant lines covered (45.53%)

6.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

52.65
/src/main/scala/io/github/srs/utils/SimulationDefaults.scala
1
package io.github.srs.utils
2

3
import java.awt.Color
4
import java.util.UUID
5

6
import scala.concurrent.duration.{ DurationInt, FiniteDuration }
7

8
import cats.effect.unsafe.implicits.global
9
import io.github.srs.model.entity.*
10
import io.github.srs.model.entity.dynamicentity.Robot
11
import io.github.srs.model.entity.dynamicentity.actuator.{ Actuator, Wheel as ActWheel }
12
import io.github.srs.model.entity.dynamicentity.behavior.Policy
13
import io.github.srs.model.entity.dynamicentity.sensor.*
14
import io.github.srs.model.environment.Environment
15
import cats.effect.IO
16
import io.github.srs.model.illumination.LightMap
17
import io.github.srs.model.illumination.engine.SquidLibFovEngine
18
import io.github.srs.model.illumination.model.ScaleFactor
19

20
object SimulationDefaults:
21

×
22
  object Illumination:
23

3✔
24
    val GridThreshold = 10_000
25
    val LightThreshold = 2
8✔
26

5✔
27
    object Occlusion:
28
      val FullRotation: Double = 90.0
3✔
29
      val AlmostZero: Double = 1e-6
8✔
30

5✔
31
  object UI:
32

×
33
    object SimulationViewConstants:
34
      val IdDisplayLength = 8
×
35
      val PositionDecimals = 2
×
36
      val OrientationDecimals = 1
×
37
      val DefaultRobotInfo = "Select a robot to view details"
×
38
      val StopConfirmMessage = "Are you sure you want to stop the simulation?\n\nClick Yes to stop, No to continue."
×
39
      val StopConfirmTitle = "Stop Simulation"
×
40

×
41
    object Colors:
42
      @inline private def rgb(r: Int, g: Int, b: Int) = new java.awt.Color(r, g, b)
×
43
      @inline private def rgba(r: Int, g: Int, b: Int, a: Int) = new java.awt.Color(r, g, b, a)
×
44
      def backgroundLight: Color = rgb(250, 250, 250)
×
45
      def backgroundMedium: Color = rgb(245, 245, 245)
×
46
      def border: Color = rgb(200, 200, 200)
×
47
      def text: Color = rgb(60, 60, 60)
×
48
      def obstacleGradientStart: Color = rgb(120, 120, 120)
×
49
      def obstacleGradientEnd: Color = rgb(80, 80, 80)
×
50
      def obstacleBorder: Color = rgb(60, 60, 60)
×
51
      def robotDefault: Color = rgb(100, 150, 255)
×
52
      def robotDefaultDark: Color = rgb(50, 100, 200)
×
53
      def robotDefaultBorder: Color = rgb(0, 50, 150)
×
54
      def robotSelected: Color = rgb(255, 100, 100)
×
55
      def robotSelectedDark: Color = rgb(200, 50, 50)
×
56
      def robotSelectedBorder: Color = rgb(150, 0, 0)
×
57
      def robotShadow: Color = rgba(0, 0, 0, 50)
×
58
      def lightCenter: Color = rgba(255, 255, 200, 200)
×
59
      def lightEdge: Color = rgba(255, 140, 0, 80)
×
60
      def buttonHover: Color = rgb(230, 230, 230)
×
61
      def buttonPressed: Color = rgb(220, 235, 250)
×
62
      def timeDisplay: Color = rgb(50, 50, 50)
×
63

×
64
    end Colors
65

66
    object Fonts:
67
      val fontSize = 12
×
68
      val titleSize = 12
×
69

×
70
    object Spacing:
71
      val standardPadding = 10
×
72
      val innerPadding = 5
×
73
      val componentGap = 10
×
74

×
75
    object Dimensions:
76
      val buttonWidth = 150
×
77
      val buttonHeight = 30
×
78
      val robotListWidth = 250
×
79
      val robotListHeight = 300
×
80
      val infoAreaRows = 6
×
81
      val infoAreaColumns = 25
×
82

×
83
    object Strokes:
84
      val obstacleStroke = 1.5f
×
85
      val robotShadowStroke = 3f
×
86

×
87
    object Icons:
88
      val play = "\u25B6"
×
89
      val stop = "\u23F9"
×
90
      val pause = "\u23F8"
×
91
  end UI
×
92

93
  val duration: Option[Long] = None
94
  val seed: Option[Long] = None
8✔
95
  val debugMode = true
4✔
96
  val binarySearchDurationThreshold: FiniteDuration = 1.microseconds
2✔
97

13✔
98
  /**
99
   * Alternative light map configurations for different use cases
100
   */
101
  object LightMapConfigs:
102

3✔
103
    /**
104
     * Default light map with caching enabled Uses scale factor 10 for a good balance of performance and precision
105
     */
106
    lazy val baseLightMap: LightMap[IO] =
107
      LightMap
11✔
108
        .create[IO](ScaleFactor.default, SquidLibFovEngine)
30✔
109
        .unsafeRunSync()
19✔
110

68✔
111
    /**
112
     * High-precision light map for detailed rendering Uses scale factor 100 for maximum precision.
113
     *
114
     * @return
115
     *   A [[LightMap]] configured for high precision, or the default light map if the scale factor is invalid.
116
     */
117
    def HPLightMap: LightMap[IO] =
NEW
118
      ScaleFactor
×
NEW
119
        .validate(80)
×
NEW
120
        .map { scale =>
×
NEW
121
          LightMap
×
122
            .create[IO](scale, SquidLibFovEngine)
123
            .unsafeRunSync()
124
        }
NEW
125
        .getOrElse(baseLightMap)
×
NEW
126

×
127
    /**
128
     * Fast light map for real-time simulation Uses scale factor 5 for maximum performance.
129
     *
130
     * @return
131
     *   A [[LightMap]] configured for fast computation, or the default light map if the scale factor is invalid.
132
     */
133
    def fastLightMap: LightMap[IO] =
NEW
134
      ScaleFactor
×
NEW
135
        .validate(10)
×
NEW
136
        .map { scale =>
×
NEW
137
          LightMap
×
138
            .create[IO](scale, SquidLibFovEngine)
139
            .unsafeRunSync()
140
        }
NEW
141
        .getOrElse(baseLightMap)
×
NEW
142

×
143
    /**
144
     * Custom light map with specific scale factor Curried for better composition.
145
     *
146
     * @param scaleFactor
147
     *   The desired scale factor (cells per meter).
148
     * @return
149
     *   A [[LightMap]] configured with the specified scale factor, or the default light map if the scale factor is
150
     *   invalid.
151
     */
152
    def withScale(scaleFactor: Int): LightMap[IO] =
NEW
153
      ScaleFactor
×
NEW
154
        .validate(scaleFactor)
×
NEW
155
        .map { scale =>
×
NEW
156
          LightMap
×
157
            .create[IO](scale, SquidLibFovEngine)
158
            .unsafeRunSync()
159
        }
NEW
160
        .getOrElse(baseLightMap)
×
NEW
161

×
162
  end LightMapConfigs
163

164
  object SimulationConfig:
165
    val maxCount = 10_000
×
166

×
167
  object Environment:
168
    val defaultWidth: Int = 10
3✔
169
    val minWidth: Int = 1
8✔
170
    val maxWidth: Int = 500
4✔
171

4✔
172
    val defaultHeight: Int = 10
173
    val minHeight: Int = 1
4✔
174
    val maxHeight: Int = 500
4✔
175

4✔
176
    val defaultEntities: Set[Entity] = Set.empty
177
    val maxEntities: Int = 200
10✔
178

5✔
179
  object StaticEntity:
180

×
181
    object Obstacle:
182
      val defaultId: UUID = UUID.fromString("00000000-0000-0000-0000-000000000000")
3✔
183
      val defaultPosition: Point2D = (0.0, 0.0)
13✔
184
      val defaultOrientation: Orientation = Orientation(0.0)
8✔
185
      val defaultWidth: Double = 1.0
10✔
186
      val defaultHeight: Double = 1.0
4✔
187

5✔
188
    object Light:
189
      val defaultId: UUID = UUID.fromString("00000000-0000-0000-0000-000000000001")
3✔
190
      val defaultPosition: Point2D = (0.0, 0.0)
13✔
191
      val defaultOrientation: Orientation = Orientation(0.0)
8✔
192
      val defaultRadius: Double = 0.05
10✔
193
      val defaultIlluminationRadius: Double = 1.0
4✔
194
      val defaultIntensity: Double = 1.0
4✔
195
      val defaultAttenuation: Double = 1.0
4✔
196

5✔
197
    object Boundary:
198
      val defaultPosition: Point2D = (0.0, 0.0)
3✔
199
      val defaultOrientation: Orientation = Orientation(0.0)
12✔
200
      val defaultWidth: Double = 1.0
10✔
201
      val defaultHeight: Double = 1.0
4✔
202

5✔
203
  end StaticEntity
204

205
  object DynamicEntity:
206
    val zeroSpeed: Double = 0.0
3✔
207
    val minSpeed: Double = -1.0
8✔
208
    val maxSpeed: Double = 1.0
4✔
209
    val halfSpeed: Double = 0.5
4✔
210

5✔
211
    object Actuator:
212

×
213
      object DifferentialWheelMotor:
214
        val defaultWheel: ActWheel = ActWheel()
3✔
215

22✔
216
        object Wheel:
217
          val defaultSpeed: Double = 1.0
3✔
218
          val defaultShape: ShapeType.Circle = ShapeType.Circle(0.1)
8✔
219

7✔
220
    object Sensor:
221

×
222
      object ProximitySensor:
223
        val defaultOffset: Double = 0.0
×
224
        val defaultRange: Double = 5.0
×
225

×
226
    object Robot:
227
      import SimulationDefaults.DynamicEntity.Robot.defaultShape.radius
3✔
228

229
      val defaultMaxRetries = 10
230

6✔
231
      val defaultId: UUID = UUID.fromString("00000000-0000-0000-0000-000000000002")
232
      val defaultPosition: Point2D = (0.0, 0.0)
9✔
233
      val defaultShape: ShapeType.Circle = ShapeType.Circle(0.5)
8✔
234
      val defaultOrientation: Orientation = Orientation(0.0)
6✔
235
      val defaultActuators: Seq[Actuator[Robot]] = Seq.empty
10✔
236
      val defaultSensors: Vector[Sensor[Robot, Environment]] = Vector.empty
11✔
237

10✔
238
      val selectionStroke: Float = 3f
239
      val normalStroke: Float = 1f
2✔
240
      val arrowLengthFactor: Double = 0.6
2✔
241
      val arrowWidthFactor: Double = 0.3
2✔
242
      val minArrowWidth: Float = 2f
2✔
243

2✔
244
      val stdProximitySensors: Vector[Sensor[Robot, Environment]] = Vector(
245
        ProximitySensor(Orientation(0.0), radius),
6✔
246
        ProximitySensor(Orientation(45.0), radius),
23✔
247
        ProximitySensor(Orientation(90.0), radius),
15✔
248
        ProximitySensor(Orientation(135.0), radius),
15✔
249
        ProximitySensor(Orientation(180.0), radius),
15✔
250
        ProximitySensor(Orientation(225.0), radius),
15✔
251
        ProximitySensor(Orientation(270.0), radius),
15✔
252
        ProximitySensor(Orientation(315.0), radius),
15✔
253
      )
15✔
254

3✔
255
      val stdLightSensors: Vector[Sensor[Robot, Environment]] = Vector(
256
        LightSensor(Orientation(0.0)),
6✔
257
        LightSensor(Orientation(45.0)),
20✔
258
        LightSensor(Orientation(90.0)),
12✔
259
        LightSensor(Orientation(135.0)),
12✔
260
        LightSensor(Orientation(180.0)),
12✔
261
        LightSensor(Orientation(225.0)),
12✔
262
        LightSensor(Orientation(270.0)),
12✔
263
        LightSensor(Orientation(315.0)),
12✔
264
      )
12✔
265
      val defaultPolicy: Policy = Policy.AlwaysForward
3✔
266
    end Robot
5✔
267
  end DynamicEntity
268

269
  object Fields:
270

×
271
    object Simulation:
272
      val self: String = "simulation"
3✔
273
      val duration: String = "duration"
8✔
274
      val seed: String = "seed"
4✔
275

5✔
276
    object Environment:
277
      val self: String = "environment"
3✔
278
      val width: String = "width"
8✔
279
      val height: String = "height"
4✔
280
      val entities: String = "entities"
4✔
281

5✔
282
    object Entity:
283
      val id: String = "id"
3✔
284
      val position: String = "position"
8✔
285
      val x: String = "x"
4✔
286
      val y: String = "y"
2✔
287
      val orientation: String = "orientation"
2✔
288

5✔
289
      object StaticEntity:
290

×
291
        object Obstacle:
292
          val self: String = "obstacle"
3✔
293
          val width: String = "width"
8✔
294
          val height: String = "height"
4✔
295

5✔
296
        object Light:
297
          val self: String = "light"
3✔
298
          val radius: String = "radius"
8✔
299
          val illuminationRadius: String = "illuminationRadius"
4✔
300
          val intensity: String = "intensity"
4✔
301
          val attenuation: String = "attenuation"
4✔
302

5✔
303
      object DynamicEntity:
304

×
305
        object Robot:
306
          val self: String = "robot"
3✔
307
          val radius: String = "radius"
8✔
308
          val speed: String = "speed"
4✔
309
          val withProximitySensors: String = "withProximitySensors"
4✔
310
          val withLightSensors: String = "withLightSensors"
4✔
311
          val behavior: String = "behavior"
4✔
312
    end Entity
5✔
313
  end Fields
314

315
  object Layout:
316
    val splitPaneWeight: Double = 0.8
×
317
    val splitPaneLocation: Double = 0.8
×
318

×
319
  object Frame:
320
    val minWidth = 800
×
321
    val minHeight = 600
×
322
    val prefWidth = 1200
×
323
    val prefHeight = 720
×
324
    val splitWeight = 0.8
×
325
    val canvasBorder: Int = 2
×
326

×
327
  object Canvas:
328
    val borderSize = 2
×
329
    val minZoom = 0.2
×
330
    val maxZoom = 5.0
×
331
    val zoomInFactor = 1.2
×
332
    val zoomOutFactor = 0.8
×
333
    val desiredLabelPixels = 40.0
×
334
    val gridStrokeWidth = 1f
×
335
    val labelDesiredPx: Double = 40.0
×
336
    val minLightSize: Int = 12
×
337
    val lightStroke: Float = 2f
×
338
    val labelBottomOffset: Int = 4
×
339
    val labelYOffset: Int = 12
×
340
    val labelXOffset: Int = 2
×
341

×
342
  object ControlsPanel:
343
    val startStopButtonText: String = "Start/Stop"
×
344

×
345
end SimulationDefaults
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc