Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added images/field26.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 5 additions & 6 deletions lib/pages/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,8 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {

_animController.forward();

if (!(widget.prefs.getBool(PrefsKeys.seen2025ResetPopup) ?? false) &&
(_fieldImage?.name != 'Reefscape' &&
_fieldImage?.name != 'Reefscape (Annotated)') &&
if (!(widget.prefs.getBool(PrefsKeys.seen2026ResetPopup) ?? false) &&
(_fieldImage?.name != 'Rebuilt') &&
mounted) {
showDialog(
context: this.context,
Expand All @@ -165,22 +164,22 @@ class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
mainAxisSize: MainAxisSize.min,
children: [
Text(
'The 2025 field image is now available. Would you like to set your field image to the 2025 field and reset the navgrid to the new default?'),
'The 2026 field image is now available. Would you like to set your field image to the 2026 field and reset the navgrid to the new default?'),
],
),
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
widget.prefs.setBool(PrefsKeys.seen2025ResetPopup, true);
widget.prefs.setBool(PrefsKeys.seen2026ResetPopup, true);
},
child: const Text('No'),
),
TextButton(
onPressed: () async {
Navigator.of(context).pop();
widget.prefs.setBool(PrefsKeys.seen2025ResetPopup, true);
widget.prefs.setBool(PrefsKeys.seen2026ResetPopup, true);
setState(() {
_fieldImage = FieldImage.defaultField;
widget.prefs
Expand Down
12 changes: 7 additions & 5 deletions lib/pages/nav_grid_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,16 @@ class _NavGridPageState extends State<NavGridPage> {
}

double _xPixelsToMeters(double pixels) {
return ((pixels - 48) / _NavigationPainter.scale) /
widget.fieldImage.pixelsPerMeter;
return (((pixels - 48) / _NavigationPainter.scale) /
widget.fieldImage.pixelsPerMeter) -
widget.fieldImage.marginMeters;
}

double _yPixelsToMeters(double pixels) {
return (widget.fieldImage.defaultSize.height -
((pixels - 48) / _NavigationPainter.scale)) /
widget.fieldImage.pixelsPerMeter;
return ((widget.fieldImage.defaultSize.height -
((pixels - 48) / _NavigationPainter.scale)) /
widget.fieldImage.pixelsPerMeter) -
widget.fieldImage.marginMeters;
}

void _saveNavGrid() {
Expand Down
7 changes: 5 additions & 2 deletions lib/util/path_painter_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,12 @@ class PathPainterUtil {
static Offset pointToPixelOffset(
Translation2d point, double scale, FieldImage fieldImage) {
return Offset(
(point.x * fieldImage.pixelsPerMeter) + 0,
((point.x + fieldImage.marginMeters) * fieldImage.pixelsPerMeter) -
8,
fieldImage.defaultSize.height -
((point.y * fieldImage.pixelsPerMeter) + 0))
(((point.y + fieldImage.marginMeters) *
fieldImage.pixelsPerMeter) -
8))
.scale(scale, scale);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/util/prefs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class PrefsKeys {
static const String currentProjectDir = 'currentProjectDir';
static const String macOSBookmark = 'macOSBookmark';
static const String fieldImage = 'fieldImage';
static const String seen2025ResetPopup = 'seen2025ResetPopup';
static const String seen2026ResetPopup = 'seen2026ResetPopup';
static const String holonomicMode = 'holonomicMode';
static const String ntServerAddress = 'pplibClientHost';
static const String pathSortOption = 'pathSortOption';
Expand Down
12 changes: 7 additions & 5 deletions lib/widgets/editor/split_path_editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -848,14 +848,16 @@ class _SplitPathEditorState extends State<SplitPathEditor>
}

double _xPixelsToMeters(double pixels) {
return ((pixels - 48) / PathPainter.scale) /
widget.fieldImage.pixelsPerMeter;
return (((pixels - 48) / PathPainter.scale) /
widget.fieldImage.pixelsPerMeter) -
widget.fieldImage.marginMeters;
}

double _yPixelsToMeters(double pixels) {
return (widget.fieldImage.defaultSize.height -
((pixels - 48) / PathPainter.scale)) /
widget.fieldImage.pixelsPerMeter;
return ((widget.fieldImage.defaultSize.height -
((pixels - 48) / PathPainter.scale)) /
widget.fieldImage.pixelsPerMeter) -
widget.fieldImage.marginMeters;
}

double _pixelsToMeters(double pixels) {
Expand Down
29 changes: 26 additions & 3 deletions lib/widgets/field_image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,23 @@ enum OfficialField {
chargedUp,
crescendo,
reefscape,
reefscapeAnnotated
reefscapeAnnotated,
rebuilt
}

class FieldImage {
late final Image image;
late final ui.Size defaultSize;
late num pixelsPerMeter;
late final num marginMeters;
late String name;
late final bool isCustom;
late final String extension;

static List<FieldImage>? _officialFields;

static final FieldImage defaultField =
FieldImage.official(OfficialField.reefscape);
FieldImage.official(OfficialField.rebuilt);

static List<FieldImage> offialFields() {
_officialFields ??= [
Expand All @@ -33,6 +35,7 @@ class FieldImage {
FieldImage.official(OfficialField.crescendo),
FieldImage.official(OfficialField.reefscape),
FieldImage.official(OfficialField.reefscapeAnnotated),
FieldImage.official(OfficialField.rebuilt)
];
return _officialFields!;
}
Expand All @@ -48,6 +51,7 @@ class FieldImage {
defaultSize = const ui.Size(3240, 1620);
pixelsPerMeter = 196.85;
name = 'Rapid React';
marginMeters = 0.0;
break;
case OfficialField.chargedUp:
image = Image.asset(
Expand All @@ -58,6 +62,7 @@ class FieldImage {
defaultSize = const ui.Size(3256, 1578);
pixelsPerMeter = 196.85;
name = 'Charged Up';
marginMeters = 0.0;
break;
case OfficialField.crescendo:
image = Image.asset(
Expand All @@ -68,6 +73,7 @@ class FieldImage {
defaultSize = const ui.Size(3256, 1616);
pixelsPerMeter = 196.85;
name = 'Crescendo';
marginMeters = 0.0;
break;
case OfficialField.reefscape:
image = Image.asset(
Expand All @@ -78,6 +84,7 @@ class FieldImage {
defaultSize = const ui.Size(3510, 1610);
pixelsPerMeter = 200.0;
name = 'Reefscape';
marginMeters = 0.0;
break;
case OfficialField.reefscapeAnnotated:
image = Image.asset(
Expand All @@ -88,6 +95,18 @@ class FieldImage {
defaultSize = const ui.Size(3510, 1610);
pixelsPerMeter = 200.0;
name = 'Reefscape (Annotated)';
marginMeters = 0.0;
break;
case OfficialField.rebuilt:
image = Image.asset(
'images/field26.png',
fit: BoxFit.contain,
filterQuality: FilterQuality.medium,
);
defaultSize = const ui.Size(3508, 1814);
pixelsPerMeter = 200.0;
name = 'Rebuilt';
marginMeters = 0.5;
break;
}
isCustom = false;
Expand Down Expand Up @@ -117,10 +136,14 @@ class FieldImage {
name = fileName.substring(0, fileName.lastIndexOf('_'));
extension = fileName.substring(fileName.lastIndexOf('.') + 1);
isCustom = true;
marginMeters = 0.0;
}

ui.Size getFieldSizeMeters() {
return defaultSize / pixelsPerMeter.toDouble();
ui.Offset temp = ((defaultSize / pixelsPerMeter.toDouble()) -
ui.Size(2 * marginMeters.toDouble(), 2 * marginMeters.toDouble()))
as Offset;
return ui.Size(temp.dx, temp.dy);
}

@override
Expand Down
4 changes: 2 additions & 2 deletions pathplannerlib-python/pathplannerlib/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ def _interpolateList(a: List[float], b: List[float], t: float) -> List[float]:

class FlippingUtil:
symmetryType: FieldSymmetry = FieldSymmetry.kRotational
fieldSizeX: float = 57.573 * 0.3048 # Feet to meters
fieldSizeY: float = 26.417 * 0.3048 # Feet to meters
fieldSizeX: float = 16.54
fieldSizeY: float = 8.07 # Feet to meters

@staticmethod
def flipFieldPosition(pos: Translation2d) -> Translation2d:
Expand Down
10 changes: 5 additions & 5 deletions pathplannerlib-python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ classifiers = [
]
keywords = ["pathplannerlib"]
dependencies = [
"pyntcore >=2025.1.1",
"robotpy-wpimath >=2025.1.1",
"robotpy-commands-v2 >=2025.1.1",
"robotpy-wpiutil >=2025.1.1",
"robotpy-hal >=2025.1.1",
"pyntcore >=2026.1.1",
"robotpy-wpimath >=2026.1.1",
"robotpy-commands-v2 >=2026.1.1",
"robotpy-wpiutil >=2026.1.1",
"robotpy-hal >=2026.1.1",
"numpy >=2.1.1",
]
requires-python = ">=3.8"
Expand Down
10 changes: 5 additions & 5 deletions pathplannerlib-python/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
setuptools~=74.1.2
pyntcore>=2025.1.1
robotpy-wpimath>=2025.1.1
robotpy-commands-v2>=2025.1.1
robotpy-wpiutil>=2025.1.1
robotpy-hal>=2025.1.1
pyntcore>=2026.1.1
robotpy-wpimath>=2026.1.1
robotpy-commands-v2>=2026.1.1
robotpy-wpiutil>=2026.1.1
robotpy-hal>=2026.1.1
numpy>=2.1.1
61 changes: 41 additions & 20 deletions pathplannerlib/build.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import edu.wpi.first.toolchain.*

plugins {
id 'cpp'
id 'java'
id 'google-test'
id 'edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin' version '2025.0'
id 'edu.wpi.first.NativeUtils' version '2026.0.0'
id 'edu.wpi.first.NativeUtils' version '2026.0.1'
id 'edu.wpi.first.GradleJni' version '1.1.0'
id 'edu.wpi.first.GradleVsCode' version '2.1.0'
id 'com.diffplug.spotless' version '6.23.3'
id 'com.diffplug.spotless' version '8.0.0'
id 'jacoco'
}

ext.getCurrentArch = {
return NativePlatforms.desktop
}

def systemArch = getCurrentArch()

// WPILib Version
ext.wpilibVersion = "2026.+"

Expand Down Expand Up @@ -41,16 +49,17 @@ dependencies {
implementation "edu.wpi.first.wpiunits:wpiunits-java:$wpilibVersion"
implementation "edu.wpi.first.hal:hal-java:$wpilibVersion"
implementation "edu.wpi.first.wpilibNewCommands:wpilibNewCommands-java:$wpilibVersion"
implementation "org.ejml:ejml-simple:0.43.1"
implementation "com.fasterxml.jackson.core:jackson-annotations:2.15.2"
implementation "com.fasterxml.jackson.core:jackson-core:2.15.2"
implementation "com.fasterxml.jackson.core:jackson-databind:2.15.2"
implementation "org.ejml:ejml-simple:0.44.0"
implementation "com.fasterxml.jackson.core:jackson-annotations:2.19.2"
implementation "com.fasterxml.jackson.core:jackson-core:2.19.2"
implementation "com.fasterxml.jackson.core:jackson-databind:2.19.2"
implementation 'edu.wpi.first.thirdparty.frc2025.opencv:opencv-java:4.10.0-2'

testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.9.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
testRuntimeOnly "us.hebi.quickbuf:quickbuf-runtime:1.3.2"
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.13.4'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.13.4'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.13.4'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
testRuntimeOnly "us.hebi.quickbuf:quickbuf-runtime:1.4"
}

// Set up exports properly
Expand Down Expand Up @@ -114,6 +123,17 @@ model {
}

nativeUtils.useRequiredLibrary(it, "wpilib_executable_shared", "googletest_static")

binaries.all {
def arch = it.targetPlatform.name
if (systemArch == arch && it.buildType.name == 'debug') {
def filePath = it.tasks.install.installDirectory.get().toString() + File.separatorChar + 'lib'
test.dependsOn it.tasks.install
test.systemProperty 'java.library.path', filePath
test.environment 'LD_LIBRARY_PATH', filePath
test.workingDir filePath
}
}
}
}
}
Expand Down Expand Up @@ -143,7 +163,7 @@ spotless {
exclude '**/build/**', '**/build-*/**'
}
greclipse()
indentWithSpaces(4)
leadingTabsToSpaces(4)
trimTrailingWhitespace()
endWithNewline()
}
Expand All @@ -153,7 +173,7 @@ spotless {
exclude '**/build/**', '**/build-*/**'
}
trimTrailingWhitespace()
indentWithSpaces(4)
leadingTabsToSpaces(4)
endWithNewline()
}
}
Expand All @@ -168,17 +188,18 @@ javadoc {
apply from: 'publish.gradle'

wrapper {
gradleVersion '8.11'
}

jacocoTestReport {
reports {
xml.required.set(true)
}
gradleVersion = '8.14.3'
}

test {
useJUnitPlatform()
systemProperty 'junit.jupiter.extensions.autodetection.enabled', 'true'
testLogging {
events "failed"
exceptionFormat = "full"
}
}

finalizedBy jacocoTestReport
if (project.hasProperty('onlylinuxathena') || project.hasProperty('onlylinuxarm32') || project.hasProperty('onlylinuxarm64') || project.hasProperty('onlywindowsarm64')) {
test.enabled = false
}
10 changes: 1 addition & 9 deletions pathplannerlib/config.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ nativeUtils.withCrossLinuxArm64()
nativeUtils {
wpi {
configureDependencies {
wpiVersion = wpilibVersion
opencvYear = "frc2026"
wpiVersion = "2026.1.1"
niLibVersion = "2026.1.0"
opencvVersion = "4.10.0-2"
}
}
}
Expand All @@ -27,12 +25,6 @@ nativeUtils.wpi.getVendorDeps().getNativeVendor().initializeNativeDependencies()
nativeUtils.wpi.getVendorDeps().addVendorReposToMaven(false)

model {
// components {
// all {
// targetPlatform nativeUtils.wpi.platforms.roborio
// }
// }
// Uncomment this, and remove above lines to enable builds for all platforms
components {
all {
nativeUtils.useAllPlatforms(it)
Expand Down
Binary file modified pathplannerlib/gradle/wrapper/gradle-wrapper.jar
100644 → 100755
Binary file not shown.
2 changes: 1 addition & 1 deletion pathplannerlib/gradle/wrapper/gradle-wrapper.properties
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
Loading