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

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

26 Aug 2025 06:11PM UTC coverage: 45.024% (-0.6%) from 45.667%
#387

Pull #63

github

davidcohenDC
feat(simulation): add TimePanel for displaying simulation timing information
Pull Request #63: refactor: enhance simulation gui

13 of 69 new or added lines in 8 files covered. (18.84%)

3 existing lines in 3 files now uncovered.

1113 of 2472 relevant lines covered (45.02%)

6.22 hits per line

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

55.05
/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 UI:
23

×
24
    object SimulationViewConstants:
25
      val IdDisplayLength = 8
×
26
      val PositionDecimals = 2
×
27
      val OrientationDecimals = 1
×
28
      val DefaultRobotInfo = "Select a robot to view details"
×
29
      val StopConfirmMessage = "Are you sure you want to stop the simulation?\n\nClick Yes to stop, No to continue."
×
30
      val StopConfirmTitle = "Stop Simulation"
×
31

×
32
    object Colors:
33
      @inline private def rgb(r: Int, g: Int, b: Int) = new java.awt.Color(r, g, b)
×
34
      @inline private def rgba(r: Int, g: Int, b: Int, a: Int) = new java.awt.Color(r, g, b, a)
×
35
      def backgroundLight: Color = rgb(250, 250, 250)
×
36
      def backgroundMedium: Color = rgb(245, 245, 245)
×
37
      def border: Color = rgb(200, 200, 200)
×
38
      def text: Color = rgb(60, 60, 60)
×
39
      def obstacleGradientStart: Color = rgb(120, 120, 120)
×
40
      def obstacleGradientEnd: Color = rgb(80, 80, 80)
×
41
      def obstacleBorder: Color = rgb(60, 60, 60)
×
42
      def robotDefault: Color = rgb(100, 150, 255)
×
43
      def robotDefaultDark: Color = rgb(50, 100, 200)
×
44
      def robotDefaultBorder: Color = rgb(0, 50, 150)
×
45
      def robotSelected: Color = rgb(255, 100, 100)
×
46
      def robotSelectedDark: Color = rgb(200, 50, 50)
×
47
      def robotSelectedBorder: Color = rgb(150, 0, 0)
×
48
      def robotShadow: Color = rgba(0, 0, 0, 50)
×
49
      def lightCenter: Color = rgba(255, 255, 200, 200)
×
50
      def lightEdge: Color = rgba(255, 140, 0, 80)
×
51
      def buttonHover: Color = rgb(230, 230, 230)
×
52
      def buttonPressed: Color = rgb(220, 235, 250)
×
NEW
53
      def timeDisplay: Color = rgb(50, 50, 50)
×
UNCOV
54

×
55
    end Colors
56

57
    object Fonts:
NEW
58
      val fontSize = 12
×
59
      val titleSize = 12
×
60

×
61
    object Spacing:
62
      val standardPadding = 10
×
63
      val innerPadding = 5
×
64
      val componentGap = 10
×
65

×
66
    object Dimensions:
67
      val buttonWidth = 150
×
68
      val buttonHeight = 30
×
69
      val robotListWidth = 250
×
70
      val robotListHeight = 300
×
71
      val infoAreaRows = 6
×
72
      val infoAreaColumns = 25
×
73

×
74
    object Strokes:
75
      val obstacleStroke = 1.5f
×
76
      val robotShadowStroke = 3f
×
77

×
78
    object Icons:
79
      val play = "\u25B6"
×
80
      val stop = "\u23F9"
×
81
      val pause = "\u23F8"
×
82
  end UI
×
83

84
  val duration: Option[Long] = None
85
  val seed: Option[Long] = None
8✔
86
  val debugMode = true
4✔
87
  val binarySearchDurationThreshold: FiniteDuration = 1.microseconds
2✔
88
  val lightMap: LightMap[IO] = LightMap.create[IO](SquidLibFovEngine, ScaleFactor.default).unsafeRunSync()
12✔
89

36✔
90
  object SimulationConfig:
91
    val maxCount = 10_000
×
92

×
93
  object Environment:
94
    val defaultWidth: Int = 10
3✔
95
    val minWidth: Int = 1
8✔
96
    val maxWidth: Int = 500
4✔
97

4✔
98
    val defaultHeight: Int = 10
99
    val minHeight: Int = 1
4✔
100
    val maxHeight: Int = 500
4✔
101

4✔
102
    val defaultEntities: Set[Entity] = Set.empty
103
    val maxEntities: Int = 200
10✔
104

5✔
105
  object StaticEntity:
106

×
107
    object Obstacle:
108
      val defaultId: UUID = UUID.fromString("00000000-0000-0000-0000-000000000000")
3✔
109
      val defaultPosition: Point2D = (0.0, 0.0)
13✔
110
      val defaultOrientation: Orientation = Orientation(0.0)
8✔
111
      val defaultWidth: Double = 1.0
10✔
112
      val defaultHeight: Double = 1.0
4✔
113

5✔
114
    object Light:
115
      val defaultId: UUID = UUID.fromString("00000000-0000-0000-0000-000000000001")
3✔
116
      val defaultPosition: Point2D = (0.0, 0.0)
13✔
117
      val defaultOrientation: Orientation = Orientation(0.0)
8✔
118
      val defaultRadius: Double = 0.05
10✔
119
      val defaultIlluminationRadius: Double = 1.0
4✔
120
      val defaultIntensity: Double = 1.0
4✔
121
      val defaultAttenuation: Double = 1.0
4✔
122

5✔
123
    object Boundary:
124
      val defaultPosition: Point2D = (0.0, 0.0)
3✔
125
      val defaultOrientation: Orientation = Orientation(0.0)
12✔
126
      val defaultWidth: Double = 1.0
10✔
127
      val defaultHeight: Double = 1.0
4✔
128

5✔
129
  end StaticEntity
130

131
  object DynamicEntity:
132
    val zeroSpeed: Double = 0.0
3✔
133
    val minSpeed: Double = -1.0
8✔
134
    val maxSpeed: Double = 1.0
4✔
135
    val halfSpeed: Double = 0.5
4✔
136

5✔
137
    object Actuator:
138

×
139
      object DifferentialWheelMotor:
140
        val defaultWheel: ActWheel = ActWheel()
3✔
141

22✔
142
        object Wheel:
143
          val defaultSpeed: Double = 1.0
3✔
144
          val defaultShape: ShapeType.Circle = ShapeType.Circle(0.1)
8✔
145

7✔
146
    object Sensor:
147

×
148
      object ProximitySensor:
149
        val defaultOffset: Double = 0.0
×
150
        val defaultRange: Double = 5.0
×
151

×
152
    object Robot:
153
      import SimulationDefaults.DynamicEntity.Robot.defaultShape.radius
3✔
154

155
      val defaultMaxRetries = 10
156

6✔
157
      val defaultId: UUID = UUID.fromString("00000000-0000-0000-0000-000000000002")
158
      val defaultPosition: Point2D = (0.0, 0.0)
9✔
159
      val defaultShape: ShapeType.Circle = ShapeType.Circle(0.5)
8✔
160
      val defaultOrientation: Orientation = Orientation(0.0)
6✔
161
      val defaultActuators: Seq[Actuator[Robot]] = Seq.empty
10✔
162
      val defaultSensors: Vector[Sensor[Robot, Environment]] = Vector.empty
11✔
163

10✔
164
      val selectionStroke: Float = 3f
165
      val normalStroke: Float = 1f
2✔
166
      val arrowLengthFactor: Double = 0.6
2✔
167
      val arrowWidthFactor: Double = 0.3
2✔
168
      val minArrowWidth: Float = 2f
2✔
169

2✔
170
      val stdProximitySensors: Vector[Sensor[Robot, Environment]] = Vector(
171
        ProximitySensor(Orientation(0.0), radius),
6✔
172
        ProximitySensor(Orientation(45.0), radius),
23✔
173
        ProximitySensor(Orientation(90.0), radius),
15✔
174
        ProximitySensor(Orientation(135.0), radius),
15✔
175
        ProximitySensor(Orientation(180.0), radius),
15✔
176
        ProximitySensor(Orientation(225.0), radius),
15✔
177
        ProximitySensor(Orientation(270.0), radius),
15✔
178
        ProximitySensor(Orientation(315.0), radius),
15✔
179
      )
15✔
180

3✔
181
      val stdLightSensors: Vector[Sensor[Robot, Environment]] = Vector(
182
        LightSensor(Orientation(0.0)),
6✔
183
        LightSensor(Orientation(45.0)),
20✔
184
        LightSensor(Orientation(90.0)),
12✔
185
        LightSensor(Orientation(135.0)),
12✔
186
        LightSensor(Orientation(180.0)),
12✔
187
        LightSensor(Orientation(225.0)),
12✔
188
        LightSensor(Orientation(270.0)),
12✔
189
        LightSensor(Orientation(315.0)),
12✔
190
      )
12✔
191
      val defaultPolicy: Policy = Policy.AlwaysForward
3✔
192
    end Robot
5✔
193
  end DynamicEntity
194

195
  object Fields:
196

×
197
    object Simulation:
198
      val self: String = "simulation"
3✔
199
      val duration: String = "duration"
8✔
200
      val seed: String = "seed"
4✔
201

5✔
202
    object Environment:
203
      val self: String = "environment"
3✔
204
      val width: String = "width"
8✔
205
      val height: String = "height"
4✔
206
      val entities: String = "entities"
4✔
207

5✔
208
    object Entity:
209
      val id: String = "id"
3✔
210
      val position: String = "position"
8✔
211
      val x: String = "x"
4✔
212
      val y: String = "y"
2✔
213
      val orientation: String = "orientation"
2✔
214

5✔
215
      object StaticEntity:
216

×
217
        object Obstacle:
218
          val self: String = "obstacle"
3✔
219
          val width: String = "width"
8✔
220
          val height: String = "height"
4✔
221

5✔
222
        object Light:
223
          val self: String = "light"
3✔
224
          val radius: String = "radius"
8✔
225
          val illuminationRadius: String = "illuminationRadius"
4✔
226
          val intensity: String = "intensity"
4✔
227
          val attenuation: String = "attenuation"
4✔
228

5✔
229
      object DynamicEntity:
230

×
231
        object Robot:
232
          val self: String = "robot"
3✔
233
          val radius: String = "radius"
8✔
234
          val speed: String = "speed"
4✔
235
          val withProximitySensors: String = "withProximitySensors"
4✔
236
          val withLightSensors: String = "withLightSensors"
4✔
237
          val behavior: String = "behavior"
4✔
238
    end Entity
5✔
239
  end Fields
240

241
  object Layout:
242
    val splitPaneWeight: Double = 0.8
×
243
    val splitPaneLocation: Double = 0.8
×
244

×
245
  object Frame:
246
    val minWidth = 800
×
247
    val minHeight = 600
×
248
    val prefWidth = 1200
×
249
    val prefHeight = 720
×
250
    val splitWeight = 0.8
×
251
    val canvasBorder: Int = 2
×
252

×
253
  object Canvas:
254
    val borderSize = 2
×
255
    val minZoom = 0.2
×
256
    val maxZoom = 5.0
×
257
    val zoomInFactor = 1.2
×
258
    val zoomOutFactor = 0.8
×
259
    val desiredLabelPixels = 40.0
×
260
    val gridStrokeWidth = 1f
×
261
    val labelDesiredPx: Double = 40.0
×
262
    val minLightSize: Int = 12
×
263
    val lightStroke: Float = 2f
×
264
    val labelBottomOffset: Int = 4
×
265
    val labelYOffset: Int = 12
×
266
    val labelXOffset: Int = 2
×
267

×
268
  object ControlsPanel:
269
    val startStopButtonText: String = "Start/Stop"
×
270

×
271
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