ftc-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +224 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +15 -0
- package/build/knowledge/dashboard.d.ts +8 -0
- package/build/knowledge/dashboard.js +843 -0
- package/build/knowledge/examples.d.ts +1 -0
- package/build/knowledge/examples.js +1800 -0
- package/build/knowledge/ftc-sdk.d.ts +8 -0
- package/build/knowledge/ftc-sdk.js +1088 -0
- package/build/knowledge/ftclib.d.ts +10 -0
- package/build/knowledge/ftclib.js +1403 -0
- package/build/knowledge/gradle.d.ts +8 -0
- package/build/knowledge/gradle.js +956 -0
- package/build/knowledge/hardware.d.ts +22 -0
- package/build/knowledge/hardware.js +1949 -0
- package/build/knowledge/panels.d.ts +10 -0
- package/build/knowledge/panels.js +572 -0
- package/build/knowledge/pedro.d.ts +8 -0
- package/build/knowledge/pedro.js +1548 -0
- package/build/knowledge/roadrunner.d.ts +3 -0
- package/build/knowledge/roadrunner.js +481 -0
- package/build/knowledge/vision.d.ts +12 -0
- package/build/knowledge/vision.js +1869 -0
- package/build/prompts/registry.d.ts +2 -0
- package/build/prompts/registry.js +634 -0
- package/build/resources/registry.d.ts +2 -0
- package/build/resources/registry.js +520 -0
- package/build/server.d.ts +2 -0
- package/build/server.js +17 -0
- package/build/tools/registry.d.ts +2 -0
- package/build/tools/registry.js +660 -0
- package/package.json +34 -0
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PANELS_KNOWLEDGE = void 0;
|
|
4
|
+
exports.PANELS_KNOWLEDGE = {
|
|
5
|
+
overview: `
|
|
6
|
+
## Panels — All-in-One FTC Dashboard (by Lazar)
|
|
7
|
+
|
|
8
|
+
### What is Panels?
|
|
9
|
+
Panels (by Lazar, team 19234 ByteForce) is a modern, plugin-driven dashboard for FTC robots. It is an alternative to (and replacement for) FTC Dashboard (acmerobotics). Panels provides a richer feature set with a plugin architecture, wireless Limelight control, gamepad support, capture/replay, real-time configurables, field drawing, graphing, and more.
|
|
10
|
+
|
|
11
|
+
**Website:** https://panels.bylazar.com
|
|
12
|
+
**GitHub:** https://github.com/ftcontrol/ftcontrol-panels
|
|
13
|
+
**Current version:** 1.0.12 (FullPanels), 1.0.5 (Core)
|
|
14
|
+
|
|
15
|
+
### Key Differences from FTC Dashboard
|
|
16
|
+
| Feature | FTC Dashboard | Panels |
|
|
17
|
+
|---------|--------------|--------|
|
|
18
|
+
| Live variable tuning | \`@Config\` + \`public static\` | \`@Configurable\` annotation (supports more types) |
|
|
19
|
+
| Telemetry | MultipleTelemetry / TelemetryPacket | \`PanelsTelemetry.telemetry\` (drop-in) |
|
|
20
|
+
| Field overlay | Canvas API via TelemetryPacket | \`PanelsField.field\` with cursor-based drawing |
|
|
21
|
+
| Camera streaming | CameraStreamSource interface | Built-in CameraStream plugin |
|
|
22
|
+
| Limelight control | Not supported | Full wireless Limelight 3A dashboard |
|
|
23
|
+
| Gamepad | Single gamepad via browser | Up to 2 gamepads (Driver 1 + Driver 2) |
|
|
24
|
+
| Graphing | Auto-graph numeric telemetry | Dedicated Graph plugin |
|
|
25
|
+
| Capture/replay | Not supported | Record and replay debug data |
|
|
26
|
+
| Theming | Fixed UI | Full theme customization (colors, layout, widgets) |
|
|
27
|
+
| Architecture | Monolithic | Plugin-driven (extensible with custom Svelte + Kotlin plugins) |
|
|
28
|
+
| Coordinate presets | Fixed (field center origin) | Presets for Panels, Pedro Pathing, Road Runner |
|
|
29
|
+
| Battery monitoring | Not built-in | Battery plugin with real-time monitoring |
|
|
30
|
+
| Latency monitoring | Not built-in | Pinger plugin for input delay tracking |
|
|
31
|
+
| OpMode control | Basic start/stop | Full Driver Station-style with Autos/TeleOps sections + timers |
|
|
32
|
+
|
|
33
|
+
### When to Use Panels vs FTC Dashboard
|
|
34
|
+
- **Use Panels** if you want an all-in-one solution with Limelight support, capture/replay, richer configurables, gamepad, and plugin extensibility.
|
|
35
|
+
- **Use FTC Dashboard** if your team already has FTC Dashboard integrated and prefers the simpler \`@Config\` + \`MultipleTelemetry\` pattern.
|
|
36
|
+
- **Both are valid choices.** Panels is newer (v1.0) and actively developed. FTC Dashboard is more established and widely documented.
|
|
37
|
+
- **Do NOT use both simultaneously.** They both serve as web dashboards on the Control Hub and will conflict.
|
|
38
|
+
|
|
39
|
+
### Plugin Architecture
|
|
40
|
+
Panels is entirely plugin-driven. Built-in plugins include:
|
|
41
|
+
- **OpModeControl** — Driver Station-style OpMode management with Autos/TeleOps sections and timers
|
|
42
|
+
- **Telemetry** — Real-time telemetry display that mirrors Driver Hub telemetry
|
|
43
|
+
- **Configurables** — Live-tunable variables that update in real time (any data type)
|
|
44
|
+
- **Field** — Drawable canvas of the game field with mapped coordinates and pathing library presets
|
|
45
|
+
- **Graph** — Visualize live data over time for PID tuning and validation
|
|
46
|
+
- **Capture** — Record debug data and replay later for diagnosing intermittent issues
|
|
47
|
+
- **Lights** — goBILDA-style RGB indicator feedback
|
|
48
|
+
- **Battery** — Real-time battery level monitoring
|
|
49
|
+
- **Pinger** — Input delay monitoring
|
|
50
|
+
- **Gamepad** — Up to 2 FTC gamepads for wireless robot control
|
|
51
|
+
- **LimelightProxy** — Full Limelight 3A dashboard access with streaming, stats, and telemetry
|
|
52
|
+
- **CameraStream** — Optimized FTC webcam streaming
|
|
53
|
+
- **Themes** — Full UI customization (colors, layout, grid widgets, navbar navlets, tabbed groups)
|
|
54
|
+
- **Docs** — Integrated offline documentation
|
|
55
|
+
- **Utils** — Shared utilities
|
|
56
|
+
|
|
57
|
+
Custom plugins can be built with a Svelte frontend and Kotlin backend.
|
|
58
|
+
`,
|
|
59
|
+
setup: `
|
|
60
|
+
## Panels Installation & Setup
|
|
61
|
+
|
|
62
|
+
### Gradle Configuration
|
|
63
|
+
|
|
64
|
+
**Step 1:** Add the Panels Maven repository to \`build.dependencies.gradle\`:
|
|
65
|
+
\`\`\`groovy
|
|
66
|
+
repositories {
|
|
67
|
+
maven { url = 'https://mymaven.bylazar.com/releases' }
|
|
68
|
+
}
|
|
69
|
+
\`\`\`
|
|
70
|
+
|
|
71
|
+
**Step 2:** Add the FullPanels dependency (includes ALL plugins):
|
|
72
|
+
\`\`\`groovy
|
|
73
|
+
dependencies {
|
|
74
|
+
implementation 'com.bylazar:fullpanels:1.0.12'
|
|
75
|
+
}
|
|
76
|
+
\`\`\`
|
|
77
|
+
|
|
78
|
+
Or for core Panels only (no built-in plugins):
|
|
79
|
+
\`\`\`groovy
|
|
80
|
+
dependencies {
|
|
81
|
+
implementation 'com.bylazar:panels:1.0.5'
|
|
82
|
+
}
|
|
83
|
+
\`\`\`
|
|
84
|
+
|
|
85
|
+
**Step 3:** Ensure your \`build.common.gradle\` or TeamCode \`build.gradle\` has:
|
|
86
|
+
\`\`\`groovy
|
|
87
|
+
android {
|
|
88
|
+
compileSdk 34 // Panels requires API 34+
|
|
89
|
+
// ...
|
|
90
|
+
compileOptions {
|
|
91
|
+
sourceCompatibility JavaVersion.VERSION_11
|
|
92
|
+
targetCompatibility JavaVersion.VERSION_11
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
\`\`\`
|
|
96
|
+
|
|
97
|
+
**Step 4:** If using Kotlin (recommended), add the Kotlin plugin:
|
|
98
|
+
\`\`\`groovy
|
|
99
|
+
apply plugin: 'org.jetbrains.kotlin.android'
|
|
100
|
+
|
|
101
|
+
kotlinOptions {
|
|
102
|
+
jvmTarget = '11'
|
|
103
|
+
}
|
|
104
|
+
\`\`\`
|
|
105
|
+
|
|
106
|
+
**Step 5:** Create a Config class that extends PanelsConfig:
|
|
107
|
+
\`\`\`kotlin
|
|
108
|
+
import com.bylazar.panels.PanelsConfig
|
|
109
|
+
|
|
110
|
+
class Config : PanelsConfig() {
|
|
111
|
+
@Transient
|
|
112
|
+
override var isDisabled = false
|
|
113
|
+
}
|
|
114
|
+
\`\`\`
|
|
115
|
+
|
|
116
|
+
### Accessing Panels
|
|
117
|
+
| Connection Method | URL |
|
|
118
|
+
|-------------------|-----|
|
|
119
|
+
| **Control Hub** (Wi-Fi Direct) | \`http://192.168.43.1:8080/panels\` |
|
|
120
|
+
| **Phone** (Wi-Fi Direct) | \`http://192.168.49.1:8080/panels\` |
|
|
121
|
+
|
|
122
|
+
Open the URL in any modern web browser on a device connected to the Robot Controller's Wi-Fi network.
|
|
123
|
+
|
|
124
|
+
### Java Support
|
|
125
|
+
Panels is developed in Kotlin but works in Java too. For Java users, the APIs are the same but you access singleton objects differently:
|
|
126
|
+
\`\`\`java
|
|
127
|
+
// Kotlin
|
|
128
|
+
val telemetry = PanelsTelemetry.telemetry;
|
|
129
|
+
|
|
130
|
+
// Java
|
|
131
|
+
Telemetry telemetry = PanelsTelemetry.INSTANCE.getTelemetry();
|
|
132
|
+
\`\`\`
|
|
133
|
+
|
|
134
|
+
### IMPORTANT: Panels vs FTC Dashboard
|
|
135
|
+
Do NOT install both Panels and FTC Dashboard. They are alternative dashboards — using both will create conflicts. If migrating from FTC Dashboard:
|
|
136
|
+
1. Remove the FTC Dashboard dependency (\`com.acmerobotics.dashboard:dashboard\`)
|
|
137
|
+
2. Remove the brott.dev Maven repository (if only used for dashboard)
|
|
138
|
+
3. Replace \`@Config\` with \`@Configurable\`
|
|
139
|
+
4. Replace \`MultipleTelemetry\` with \`PanelsTelemetry.telemetry\`
|
|
140
|
+
5. Replace \`TelemetryPacket.fieldOverlay()\` with \`PanelsField.field\`
|
|
141
|
+
`,
|
|
142
|
+
configurables: `
|
|
143
|
+
## Panels Configurables — Live Variable Tuning
|
|
144
|
+
|
|
145
|
+
### @Configurable Annotation
|
|
146
|
+
Panels uses the \`@Configurable\` annotation (from \`com.bylazar.configurables.annotations\`) to expose variables for live tuning. This is the Panels equivalent of FTC Dashboard's \`@Config\`.
|
|
147
|
+
|
|
148
|
+
### Import
|
|
149
|
+
\`\`\`kotlin
|
|
150
|
+
import com.bylazar.configurables.annotations.Configurable
|
|
151
|
+
import com.bylazar.configurables.PanelsConfigurables
|
|
152
|
+
\`\`\`
|
|
153
|
+
|
|
154
|
+
### Basic Usage (Kotlin)
|
|
155
|
+
\`\`\`kotlin
|
|
156
|
+
@Configurable
|
|
157
|
+
object RobotConstants {
|
|
158
|
+
@JvmField var DRIVE_SPEED = 0.8
|
|
159
|
+
@JvmField var ENCODER_TICKS = 1120
|
|
160
|
+
@JvmField var USE_GYRO = true
|
|
161
|
+
}
|
|
162
|
+
\`\`\`
|
|
163
|
+
|
|
164
|
+
### Usage on OpMode Classes (Kotlin)
|
|
165
|
+
\`\`\`kotlin
|
|
166
|
+
@Configurable
|
|
167
|
+
@TeleOp(name = "My TeleOp", group = "Dev")
|
|
168
|
+
class MyTeleOp : OpMode() {
|
|
169
|
+
companion object {
|
|
170
|
+
@JvmField var armPower = 0.5
|
|
171
|
+
@JvmField var slowMode = false
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
override fun init() {
|
|
175
|
+
PanelsConfigurables.refreshClass(this)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
override fun loop() {
|
|
179
|
+
// armPower and slowMode update live from the Panels dashboard
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
\`\`\`
|
|
183
|
+
|
|
184
|
+
### Refreshing Configurables
|
|
185
|
+
Call \`PanelsConfigurables.refreshClass()\` to register a class's configurable values with the dashboard:
|
|
186
|
+
\`\`\`kotlin
|
|
187
|
+
// In init()
|
|
188
|
+
PanelsConfigurables.refreshClass(MyConstants)
|
|
189
|
+
PanelsConfigurables.refreshClass(this) // for the OpMode itself if @Configurable
|
|
190
|
+
\`\`\`
|
|
191
|
+
|
|
192
|
+
### Supported Types
|
|
193
|
+
Panels Configurables supports a broader set of types than FTC Dashboard's @Config:
|
|
194
|
+
- Primitives: \`Int\`, \`Long\`, \`Double\`, \`Float\`, \`Boolean\`
|
|
195
|
+
- \`String\`
|
|
196
|
+
- \`enum\` types
|
|
197
|
+
- Arrays (including mixed-type arrays)
|
|
198
|
+
- Lists and Maps
|
|
199
|
+
- Custom objects (recursively expands fields)
|
|
200
|
+
- Nested types (deeply nested custom objects)
|
|
201
|
+
- Generic types (with \`@GenericValue\` annotation)
|
|
202
|
+
- Nullable types
|
|
203
|
+
|
|
204
|
+
### Custom Object Example
|
|
205
|
+
\`\`\`kotlin
|
|
206
|
+
@Configurable
|
|
207
|
+
object PIDConstants {
|
|
208
|
+
class PIDCoefficients(
|
|
209
|
+
val kP: Double,
|
|
210
|
+
val kI: Double,
|
|
211
|
+
val kD: Double
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
@JvmField var DRIVE_PID = PIDCoefficients(0.05, 0.0, 0.01)
|
|
215
|
+
@JvmField var ARM_PID = PIDCoefficients(0.1, 0.0, 0.02)
|
|
216
|
+
}
|
|
217
|
+
\`\`\`
|
|
218
|
+
|
|
219
|
+
### Generic Type Support
|
|
220
|
+
For generic/parameterized types, use the \`@GenericValue\` annotation:
|
|
221
|
+
\`\`\`kotlin
|
|
222
|
+
import com.bylazar.configurables.annotations.GenericValue
|
|
223
|
+
|
|
224
|
+
class TParamClass<T>(val test: T)
|
|
225
|
+
|
|
226
|
+
@Configurable
|
|
227
|
+
object MyConfig {
|
|
228
|
+
@JvmField
|
|
229
|
+
@field:GenericValue(Int::class)
|
|
230
|
+
var testTParamClass = TParamClass(1)
|
|
231
|
+
}
|
|
232
|
+
\`\`\`
|
|
233
|
+
|
|
234
|
+
### Java Usage
|
|
235
|
+
\`\`\`java
|
|
236
|
+
import com.bylazar.configurables.annotations.Configurable;
|
|
237
|
+
import com.bylazar.configurables.PanelsConfigurables;
|
|
238
|
+
|
|
239
|
+
@Configurable
|
|
240
|
+
public class RobotConstants {
|
|
241
|
+
public static double DRIVE_SPEED = 0.8;
|
|
242
|
+
public static int ENCODER_TICKS = 1120;
|
|
243
|
+
public static boolean USE_GYRO = true;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// In your OpMode init:
|
|
247
|
+
PanelsConfigurables.INSTANCE.refreshClass(RobotConstants.class);
|
|
248
|
+
\`\`\`
|
|
249
|
+
|
|
250
|
+
### Key Differences from FTC Dashboard @Config
|
|
251
|
+
| FTC Dashboard | Panels |
|
|
252
|
+
|--------------|--------|
|
|
253
|
+
| \`@Config\` | \`@Configurable\` |
|
|
254
|
+
| \`public static\` fields only | \`@JvmField var\` (Kotlin) or \`public static\` (Java) |
|
|
255
|
+
| No arrays/maps/generics | Full support for arrays, lists, maps, generics |
|
|
256
|
+
| Reflection-based | Kotlin reflection with broader type support |
|
|
257
|
+
| \`FtcDashboard.getInstance()\` | \`PanelsConfigurables.refreshClass()\` |
|
|
258
|
+
`,
|
|
259
|
+
telemetry: `
|
|
260
|
+
## Panels Telemetry
|
|
261
|
+
|
|
262
|
+
### Getting the Telemetry Instance
|
|
263
|
+
\`\`\`kotlin
|
|
264
|
+
import com.bylazar.telemetry.PanelsTelemetry
|
|
265
|
+
|
|
266
|
+
val telemetry = PanelsTelemetry.telemetry
|
|
267
|
+
\`\`\`
|
|
268
|
+
|
|
269
|
+
The \`PanelsTelemetry.telemetry\` object provides a telemetry interface that sends data to the Panels dashboard. It mirrors Driver Hub telemetry so data stays consistent.
|
|
270
|
+
|
|
271
|
+
### Basic Usage (Kotlin)
|
|
272
|
+
\`\`\`kotlin
|
|
273
|
+
import com.bylazar.telemetry.PanelsTelemetry
|
|
274
|
+
import com.qualcomm.robotcore.eventloop.opmode.OpMode
|
|
275
|
+
import com.qualcomm.robotcore.eventloop.opmode.TeleOp
|
|
276
|
+
|
|
277
|
+
@TeleOp(name = "Panels Telemetry Demo")
|
|
278
|
+
class TelemetryDemo : OpMode() {
|
|
279
|
+
val telemetry = PanelsTelemetry.telemetry
|
|
280
|
+
|
|
281
|
+
override fun init() {
|
|
282
|
+
telemetry.debug("Init was called")
|
|
283
|
+
telemetry.update()
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
override fun loop() {
|
|
287
|
+
telemetry.debug("Loop at \${System.currentTimeMillis()}")
|
|
288
|
+
telemetry.debug("Heading: \${getHeading()}")
|
|
289
|
+
telemetry.update() // Must call update() to send data
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
\`\`\`
|
|
293
|
+
|
|
294
|
+
### Telemetry Methods
|
|
295
|
+
| Method | Description |
|
|
296
|
+
|--------|-------------|
|
|
297
|
+
| \`debug(message: String)\` | Add a debug/info line to telemetry |
|
|
298
|
+
| \`update()\` | Send all queued telemetry data to the dashboard |
|
|
299
|
+
|
|
300
|
+
### Configuring Telemetry Plugin
|
|
301
|
+
Create a config class extending TelemetryPluginConfig:
|
|
302
|
+
\`\`\`kotlin
|
|
303
|
+
import com.bylazar.telemetry.TelemetryPluginConfig
|
|
304
|
+
|
|
305
|
+
class TelemetryConfig : TelemetryPluginConfig() {
|
|
306
|
+
@Transient
|
|
307
|
+
override var telemetryUpdateInterval = 100L // ms between updates
|
|
308
|
+
}
|
|
309
|
+
\`\`\`
|
|
310
|
+
|
|
311
|
+
### Java Usage
|
|
312
|
+
\`\`\`java
|
|
313
|
+
import com.bylazar.telemetry.PanelsTelemetry;
|
|
314
|
+
|
|
315
|
+
@TeleOp(name = "Panels Telemetry Demo")
|
|
316
|
+
public class TelemetryDemo extends OpMode {
|
|
317
|
+
@Override
|
|
318
|
+
public void init() {
|
|
319
|
+
PanelsTelemetry.INSTANCE.getTelemetry().debug("Init");
|
|
320
|
+
PanelsTelemetry.INSTANCE.getTelemetry().update();
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
@Override
|
|
324
|
+
public void loop() {
|
|
325
|
+
PanelsTelemetry.INSTANCE.getTelemetry().debug("Running");
|
|
326
|
+
PanelsTelemetry.INSTANCE.getTelemetry().update();
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
\`\`\`
|
|
330
|
+
|
|
331
|
+
### Migration from FTC Dashboard
|
|
332
|
+
If migrating from FTC Dashboard's MultipleTelemetry:
|
|
333
|
+
\`\`\`
|
|
334
|
+
// BEFORE (FTC Dashboard):
|
|
335
|
+
telemetry = new MultipleTelemetry(telemetry, FtcDashboard.getInstance().getTelemetry());
|
|
336
|
+
telemetry.addData("Speed", speed);
|
|
337
|
+
telemetry.update();
|
|
338
|
+
|
|
339
|
+
// AFTER (Panels):
|
|
340
|
+
val telemetry = PanelsTelemetry.telemetry
|
|
341
|
+
telemetry.debug("Speed: $speed")
|
|
342
|
+
telemetry.update()
|
|
343
|
+
\`\`\`
|
|
344
|
+
`,
|
|
345
|
+
field: `
|
|
346
|
+
## Panels Field — Canvas Drawing API
|
|
347
|
+
|
|
348
|
+
### Getting the Field Instance
|
|
349
|
+
\`\`\`kotlin
|
|
350
|
+
import com.bylazar.field.PanelsField
|
|
351
|
+
|
|
352
|
+
val field = PanelsField.field
|
|
353
|
+
\`\`\`
|
|
354
|
+
|
|
355
|
+
### Coordinate System Presets
|
|
356
|
+
Panels provides coordinate system presets for popular FTC pathing libraries:
|
|
357
|
+
\`\`\`kotlin
|
|
358
|
+
// Set coordinate offsets to match your pathing library
|
|
359
|
+
field.setOffsets(PanelsField.presets.PANELS) // Panels default
|
|
360
|
+
field.setOffsets(PanelsField.presets.PEDRO_PATHING) // Pedro Pathing coordinates
|
|
361
|
+
field.setOffsets(PanelsField.presets.ROAD_RUNNER) // Road Runner coordinates
|
|
362
|
+
\`\`\`
|
|
363
|
+
This is a major advantage — no manual coordinate translation needed when using Pedro Pathing or Road Runner.
|
|
364
|
+
|
|
365
|
+
### Drawing API
|
|
366
|
+
The Panels Field API uses a cursor-based drawing model:
|
|
367
|
+
|
|
368
|
+
\`\`\`kotlin
|
|
369
|
+
// Move the drawing cursor to a position
|
|
370
|
+
field.moveCursor(x, y)
|
|
371
|
+
|
|
372
|
+
// Draw shapes at the cursor position
|
|
373
|
+
field.circle(radius) // Draw a circle
|
|
374
|
+
field.rect(width, height) // Draw a rectangle
|
|
375
|
+
field.line(endX, endY) // Draw a line from cursor to (endX, endY)
|
|
376
|
+
field.img(width, height, id) // Draw a registered image
|
|
377
|
+
|
|
378
|
+
// Style the drawings
|
|
379
|
+
field.setStyle(fillColor, strokeColor, strokeWidth)
|
|
380
|
+
|
|
381
|
+
// Send the field data to the dashboard
|
|
382
|
+
field.update()
|
|
383
|
+
\`\`\`
|
|
384
|
+
|
|
385
|
+
### Color Constants
|
|
386
|
+
\`\`\`kotlin
|
|
387
|
+
PanelsField.RED
|
|
388
|
+
PanelsField.BLUE
|
|
389
|
+
// And other CSS-compatible color constants
|
|
390
|
+
\`\`\`
|
|
391
|
+
|
|
392
|
+
### Registering and Drawing Images
|
|
393
|
+
\`\`\`kotlin
|
|
394
|
+
// Register an image (do this once, e.g., at class level)
|
|
395
|
+
val imgID = field.registerImage(PanelsField.images.DECODE.DARK)
|
|
396
|
+
|
|
397
|
+
// Draw the image at the cursor position
|
|
398
|
+
field.moveCursor(40.0, 40.0)
|
|
399
|
+
field.img(10.0, 10.0, imgID)
|
|
400
|
+
\`\`\`
|
|
401
|
+
|
|
402
|
+
### Setting the Field Background
|
|
403
|
+
\`\`\`kotlin
|
|
404
|
+
field.setBackground(PanelsField.images.DECODE.LIGHT)
|
|
405
|
+
\`\`\`
|
|
406
|
+
|
|
407
|
+
### Complete Example — Drawing Robot on Field
|
|
408
|
+
\`\`\`kotlin
|
|
409
|
+
import com.bylazar.configurables.annotations.Configurable
|
|
410
|
+
import com.bylazar.field.PanelsField
|
|
411
|
+
import com.bylazar.telemetry.PanelsTelemetry
|
|
412
|
+
import com.qualcomm.robotcore.eventloop.opmode.OpMode
|
|
413
|
+
import com.qualcomm.robotcore.eventloop.opmode.TeleOp
|
|
414
|
+
|
|
415
|
+
@Configurable
|
|
416
|
+
@TeleOp(name = "Field Drawing Demo")
|
|
417
|
+
class FieldDemo : OpMode() {
|
|
418
|
+
companion object {
|
|
419
|
+
@JvmField var config = Config.PEDRO
|
|
420
|
+
enum class Config { PANELS, PEDRO, RR }
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
val telemetry = PanelsTelemetry.telemetry
|
|
424
|
+
val field = PanelsField.field
|
|
425
|
+
|
|
426
|
+
override fun init() {
|
|
427
|
+
// Set coordinate system to match your pathing library
|
|
428
|
+
field.setOffsets(when (config) {
|
|
429
|
+
Config.PANELS -> PanelsField.presets.PANELS
|
|
430
|
+
Config.PEDRO -> PanelsField.presets.PEDRO_PATHING
|
|
431
|
+
Config.RR -> PanelsField.presets.ROAD_RUNNER
|
|
432
|
+
})
|
|
433
|
+
|
|
434
|
+
field.setBackground(PanelsField.images.DECODE.LIGHT)
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
override fun loop() {
|
|
438
|
+
// Draw robot position
|
|
439
|
+
field.moveCursor(robotX, robotY)
|
|
440
|
+
field.setStyle(PanelsField.RED, PanelsField.BLUE, 0.1)
|
|
441
|
+
field.circle(6.5) // Robot radius in inches
|
|
442
|
+
|
|
443
|
+
// Draw a target position
|
|
444
|
+
field.moveCursor(targetX, targetY)
|
|
445
|
+
field.rect(10.0, 5.0)
|
|
446
|
+
|
|
447
|
+
// Draw a path line
|
|
448
|
+
field.moveCursor(robotX, robotY)
|
|
449
|
+
field.line(targetX, targetY)
|
|
450
|
+
|
|
451
|
+
field.update()
|
|
452
|
+
|
|
453
|
+
telemetry.debug("Robot: (\$robotX, \$robotY)")
|
|
454
|
+
telemetry.update()
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
\`\`\`
|
|
458
|
+
|
|
459
|
+
### Migration from FTC Dashboard Canvas
|
|
460
|
+
If migrating from FTC Dashboard's Canvas/TelemetryPacket field overlay:
|
|
461
|
+
\`\`\`
|
|
462
|
+
// BEFORE (FTC Dashboard):
|
|
463
|
+
TelemetryPacket packet = new TelemetryPacket();
|
|
464
|
+
Canvas canvas = packet.fieldOverlay();
|
|
465
|
+
canvas.setStroke("blue").strokeCircle(robotX, robotY, 9);
|
|
466
|
+
dashboard.sendTelemetryPacket(packet);
|
|
467
|
+
|
|
468
|
+
// AFTER (Panels):
|
|
469
|
+
val field = PanelsField.field
|
|
470
|
+
field.moveCursor(robotX, robotY)
|
|
471
|
+
field.setStyle(PanelsField.BLUE, PanelsField.BLUE, 0.1)
|
|
472
|
+
field.circle(9.0)
|
|
473
|
+
field.update()
|
|
474
|
+
\`\`\`
|
|
475
|
+
`,
|
|
476
|
+
limelight: `
|
|
477
|
+
## Panels Limelight Integration
|
|
478
|
+
|
|
479
|
+
### Wireless Limelight Control
|
|
480
|
+
Panels includes a built-in LimelightProxy plugin that gives you full access to the Limelight 3A dashboard without a USB connection. This is a major advantage over FTC Dashboard which has no native Limelight support.
|
|
481
|
+
|
|
482
|
+
### Features
|
|
483
|
+
- Wirelessly stream Limelight video feed
|
|
484
|
+
- Track camera stats and telemetry
|
|
485
|
+
- Configure pipelines remotely
|
|
486
|
+
- Integrated with the Panels dashboard UI
|
|
487
|
+
|
|
488
|
+
### Configuration
|
|
489
|
+
\`\`\`kotlin
|
|
490
|
+
import com.bylazar.limelightproxy.LimelightProxyConfig
|
|
491
|
+
|
|
492
|
+
class LimelightProxyConfig : LimelightProxyConfig() {
|
|
493
|
+
@Transient
|
|
494
|
+
override var isDev = false
|
|
495
|
+
}
|
|
496
|
+
\`\`\`
|
|
497
|
+
|
|
498
|
+
### Usage
|
|
499
|
+
The Limelight proxy is a plugin that runs alongside Panels. Once configured, access the Limelight dashboard directly from the Panels web interface. The built-in widgets provide:
|
|
500
|
+
- Video streaming
|
|
501
|
+
- Camera stats tracking
|
|
502
|
+
- Telemetry logging
|
|
503
|
+
- Pipeline switching
|
|
504
|
+
|
|
505
|
+
This keeps your vision system seamlessly integrated with the rest of your dashboard without needing a separate USB connection or browser tab.
|
|
506
|
+
`,
|
|
507
|
+
plugins: `
|
|
508
|
+
## Panels Plugin Development
|
|
509
|
+
|
|
510
|
+
### Architecture
|
|
511
|
+
Panels is entirely plugin-driven. Each plugin has:
|
|
512
|
+
- A **Kotlin backend** that runs on the Control Hub
|
|
513
|
+
- A **Svelte frontend** that renders in the browser dashboard
|
|
514
|
+
- Access to the full Panels UI, JS utilities, and FTC SDK
|
|
515
|
+
|
|
516
|
+
### Built-in Plugins
|
|
517
|
+
Each plugin is a separate Gradle module:
|
|
518
|
+
| Plugin | Package | Description |
|
|
519
|
+
|--------|---------|-------------|
|
|
520
|
+
| Panels (Core) | \`com.bylazar.panels\` | Core server, plugin loader, web UI |
|
|
521
|
+
| OpModeControl | \`com.bylazar.opmodecontrol\` | Driver Station-style OpMode management |
|
|
522
|
+
| Telemetry | \`com.bylazar.telemetry\` | Real-time telemetry |
|
|
523
|
+
| Configurables | \`com.bylazar.configurables\` | Live variable tuning |
|
|
524
|
+
| Field | \`com.bylazar.field\` | Field canvas drawing |
|
|
525
|
+
| Graph | \`com.bylazar.graph\` | Data visualization over time |
|
|
526
|
+
| Capture | \`com.bylazar.capture\` | Record/replay debug data |
|
|
527
|
+
| Gamepad | \`com.bylazar.gamepad\` | Wireless gamepad support |
|
|
528
|
+
| LimelightProxy | \`com.bylazar.limelightproxy\` | Limelight 3A integration |
|
|
529
|
+
| CameraStream | \`com.bylazar.camerastream\` | FTC webcam streaming |
|
|
530
|
+
| Battery | \`com.bylazar.battery\` | Battery level monitoring |
|
|
531
|
+
| Pinger | \`com.bylazar.pinger\` | Input delay monitoring |
|
|
532
|
+
| Lights | \`com.bylazar.lights\` | RGB indicator feedback |
|
|
533
|
+
| Themes | \`com.bylazar.themes\` | UI customization |
|
|
534
|
+
| Docs | \`com.bylazar.docs\` | Integrated documentation |
|
|
535
|
+
| Utils | \`com.bylazar.utils\` | Shared utilities |
|
|
536
|
+
|
|
537
|
+
### Creating Custom Plugins
|
|
538
|
+
1. Create a new Gradle module in your project
|
|
539
|
+
2. Build a Svelte frontend for the browser UI
|
|
540
|
+
3. Build a Kotlin backend that hooks into the FTC SDK
|
|
541
|
+
4. Register your plugin with Panels
|
|
542
|
+
5. Use the Panels JS utilities, components, and API
|
|
543
|
+
|
|
544
|
+
### Auto-Update
|
|
545
|
+
Each plugin can check for updates when online, keeping your dashboard current.
|
|
546
|
+
`,
|
|
547
|
+
gamepads: `
|
|
548
|
+
## Panels Gamepad Support
|
|
549
|
+
|
|
550
|
+
### Overview
|
|
551
|
+
Panels supports up to two FTC gamepads wirelessly, giving Driver 1 and Driver 2 full control of the robot from the dashboard. Both controllers are mapped and ready to use out of the box.
|
|
552
|
+
|
|
553
|
+
### How It Works
|
|
554
|
+
- Connect gamepads to the computer running the Panels dashboard in the browser
|
|
555
|
+
- Panels forwards gamepad input to the robot as \`gamepad1\` and \`gamepad2\`
|
|
556
|
+
- Both controllers are mapped using standard FTC gamepad bindings
|
|
557
|
+
- Works alongside (or as a replacement for) the physical Driver Station
|
|
558
|
+
|
|
559
|
+
### Use Cases
|
|
560
|
+
- Testing robot code without a Driver Station
|
|
561
|
+
- Remote development and debugging
|
|
562
|
+
- Practice driving from a laptop
|
|
563
|
+
- Demonstrating robot behavior
|
|
564
|
+
|
|
565
|
+
### Comparison with FTC Dashboard Gamepad
|
|
566
|
+
| Feature | FTC Dashboard | Panels |
|
|
567
|
+
|---------|--------------|--------|
|
|
568
|
+
| Gamepad count | 1 | 2 (Driver 1 + Driver 2) |
|
|
569
|
+
| Setup | Automatic via browser | Automatic via browser |
|
|
570
|
+
| Mapping | Standard FTC | Standard FTC |
|
|
571
|
+
`,
|
|
572
|
+
};
|