wpilibsuite / allwpilib

Official Repository of WPILibJ and WPILibC
https://wpilib.org/
Other
1.05k stars 612 forks source link

AHRS crashes on startup due to RuntimeDetector removal #6823

Open truher opened 1 month ago

truher commented 1 month ago

I'm using the 2025 development version, and find that the NavX vendordep is now broken, due to 0e4d2c4, which removed RuntimeDetector.

This is AHRS.java:225, in the NavX vendordep. It uses RuntimeDetector, so it crashes on startup.

Any ideas to work around this? I'd like to use 2025 and I'd like to use NavX.

    public AHRS(SPI.Port spi_port_id, byte update_rate_hz) {
        commonInit(update_rate_hz);
        if (m_simDevice != null) {
            io = new SimIO(update_rate_hz, io_complete_sink, m_simDevice);
        } else {
            if (RuntimeDetector.isLinux() && !RuntimeDetector.isAthena() && spi_port_id == SPI.Port.kMXP) {
                io = new RegisterIOMau(update_rate_hz, io_complete_sink, board_capabilities);
            } else { 
                io = new RegisterIO(new RegisterIO_SPI(new SPI(spi_port_id)), update_rate_hz, io_complete_sink, board_capabilities);
            }
        }
        SendableRegistry.addLW(this, "navX-Sensor", spi_port_id.value);
        io_thread.start();
    }

the stack trace

Unhandled exception: java.lang.ClassNotFoundException: edu.wpi.first.util.RuntimeDetector
Error at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source): Unhandled exception: java.lang.ClassNotFoundException: edu.wpi.first.util.RuntimeDetector
The robot program quit unexpectedly. This is usually due to a code error.
The above stacktrace can help determine where the error occurred.
See https://wpilib.org/stacktrace for more information.
   from: edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:364)

at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
The startCompetition() method (or methods called by it) should have handled the exception above.
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
at com.kauailabs.navx.frc.AHRS.<init>(AHRS.java:269)
at org.team100.lib.sensors.SingleNavXGyro.<init>(SingleNavXGyro.java:42)
at org.team100.lib.sensors.GyroFactory.get(GyroFactory.java:22)
at org.team100.lib.sensors.HeadingFactory.get(HeadingFactory.java:31)
at org.team100.frc2024.RobotContainer.<init>(RobotContainer.java:156)
at org.team100.frc2024.Robot.robotInit(Robot.java:48)
at org.team100.lib.framework.TimedRobot100.startCompetition(TimedRobot100.java:122)
at edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:350)
at edu.wpi.first.wpilibj.RobotBase.startRobot(RobotBase.java:438)
at org.team100.frc2024.Main.main(Main.java:10)
PeterJohnson commented 1 month ago

There is no supported workaround. Vendor deps are often broken in development versions. You might be able to insert a copy of the old version of the RuntimeDetector class into your robot project, but that’s not guaranteed to work.

truher commented 1 month ago

ok, i'll figure it out. the curious thing is that it seems like nobody expected this particular thing to break.

you: "Do any vendor libraries use the removed functionality?"

Thad: "They shouldn't be doing so anyway if they are."

https://github.com/wpilibsuite/allwpilib/pull/6600#issuecomment-2127530879

rzblue commented 1 month ago

The 2025 development artifacts have more breaking changes than just that change. I would not rely on any vendordeps working 100% until they update to build against development.

truher commented 1 month ago

:) anything in particular come to mind in terms of broken things?

truher commented 1 month ago

OK i can answer my own question here.

I was able to work around the NavX use of RuntimeDetector, just by liberally copying the NavX java code.

But Revlib uses RuntimeLoader and JNI.

I half-heartedly tried duplicating all the revlib java code and removing the vendordep but it all seemed like a lot of work, because of JNI name mapping.

So I gave up.

I think these vendordep things tend to be updated really late, don't they? like after kick-off?

i really like getting a head start on using the new parts of wpilib (i mean, come on! Ellipse2d !!), and these breaking changes will delay that.

truher commented 1 month ago

(if anyone knows a way to remap JNI calls, so i can use the old native code with an arbitrary caller package, (not com.revrobotics), i could take another crack at it.)

spacey-sooty commented 1 month ago

ok, i'll figure it out. the curious thing is that it seems like nobody expected this particular thing to break.

you: "Do any vendor libraries use the removed functionality?"

Thad: "They shouldn't be doing so anyway if they are."

#6600 (comment)

Having looked at a few open source vendors this comments seems very wrong. Both URCL and libgrapplefrc were using RuntimeLoader.

I think these vendordep things tend to be updated really late, don't they? like after kick-off?

For a stable release? yes. For a beta release you should have one soon after the first WPILib beta release, around the end of August I believe? @PeterJohnson would be the one to ask.

i really like getting a head start on using the new parts of wpilib (i mean, come on! Ellipse2d !!), and these breaking changes will delay that.

Often these breaking changes are the new features it would really slow down development to not merge breaking changes after season it appears

spacey-sooty commented 1 month ago

(if anyone knows a way to remap JNI calls, so i can use the old native code with an arbitrary caller package, (not com.revrobotics), i could take another crack at it.)

Something like https://github.com/CurtinFRC/2024-Offseason/blob/master/src/main/java/frc/robot/URCL.java ?

truher commented 1 month ago

the issue with rev is that the class with all the native methods (CANSparkMaxJNI, I think) extends RevJNIWrapper, which consists only of the broken loader in its static initializer.

so I need to avoid loading the jni class at all, yet id like to call the same native code that its signature refers to, e.g. something like com_revrobotics_jni_cansparkmaxjni_c_sparkmax_setpointcommand(), within REVLibDriver.

it looks like maybe the "foreign function" thing in java 19 would work. are we moving to java 19 anytime soon?

PeterJohnson commented 1 month ago

We're looking at moving to the Java 21 runtime on the Rio for 2025 (we've already built the JVM). However, my understanding is that the new FFI interface does not support arm32 platforms like the Rio.

PeterJohnson commented 1 month ago

Another workaround is to build and publish allwpilib locally with the RuntimeLoader change reverted.