Desktop Simulation: NavX MXP AHRS class works in Windows, not in Linux; Compiler Difference?


A few questions concerning desktop simulation. I tend to develop code in Linux, but most of the students on the team tend to use Windows.

We’ve had good luck porting our C++ code so far to the new Command API, and now with desktop simulation, which we’ve never used.

We use a NavX MXP for an navigation unit. When we added an AHRS instance in RobotContainer, it builds fine for RoboRio, both Windows and Linux (makes sense, as they should be using the same cross-compiler). However, for desktop simulation, it builds fine under Windows, but does not link in Linux.

I’m wondering: Is this due to the GNU gcc compiler being a little more strict than Microsoft’s C++ compiler? Of is it another reason?

Here is the error we are getting on Linux:

RobotContainer.o: In function `RobotContainer::RobotContainer()':
RobotContainer.cpp:37: undefined reference to `AHRS::AHRS(frc::SPI::Port)'
collect2: error: ld returned 1 exit status

Here’s code excerpts:


// The header for the NavX MXP AHRS class
#include "AHRS.h"
class RobotContainer {
    // Declare a pointer to an AHRS system, using the NavX MXP
    AHRS* m_AHRS;
}; // end class RobotContainer


#include "RobotContainer.h"
// The constructor for the robot container
RobotContainer::RobotContainer() : m_autonomousCommand(&m_subsystem) {
  // Initialize all of your commands and subsystems here
  m_AHRS = new AHRS(k_navx_mxp_imu_port);
  // Configure the button bindings
} // end RobotContainer::RobotContainer()

From what I can tell, there is no way to wrap the offending code in C++ like one can in Java with RobotBase.isReal(), per the WPILib docs. For C++, the only recommendation is using pointers, which we did above.

The only alternative I see would be to use a pre-processor directive, i.e.

      // Initialize all of your commands and subsystems here
      m_AHRS = new AHRS(k_navx_mxp_imu_port);

Any recommendations for that?

Also, one other question/comment: In the WPILib docs:

C++ robot simulation requires that a native compiler to be installed. For Windows, this would be Visual Studio 2019 (not VS Code), macOS requires Xcode, and Linux (Ubuntu) requires the build-essential package.

It would be helpful to explain in the docs what part of Visual Studio 2019 is needed. We downloaded Visual Studio 2019 Community Edition, and installed the “Desktop Development with C++” workload. It seemed to work. Should that choice work? Hopefully teams understand that Community Edition is free, but Professional and Enterprise is not.
It appears Xcode for macOS is also free. And of course, the build-essential package is free as well.

And as always, thank you for any help!

WPILib: v2020.3.2
KauaiLabs_navX_FRC: v3.1.413
gcc: gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0

I took a look at the NavX JSON and it seems like the only platforms for which binaries are available are Windows, Linux Athena (RoboRIO) and Linux Raspbian (Raspberry Pi).

This is why your simulation code builds on Windows but fails to link on Linux (because there is no provided library to link to).

The __FRC_ROBORIO__ macro is only defined on the RoboRIO, so you can use an ifndef pre-processor directive. There are also IsReal() and IsSimulation() constexpr methods that you can use.

Thank you. That makes perfect sense now why I was getting that error undefined reference. There was no binary to refer to, thus undefined.

As far as IsReal() and IsSimulation(), I’m not seeing these documented on the API page for C++. Are they in the source, and just not documented in doxygen?

So, we should be okay to simulate on Windows, it appears.

Thanks! Greatly appreciate it!

You’re welcome!

The method signatures exist here, but you are correct in that there are no doxygen comments for these methods. I’ll open an issue for this now and try to resolve it tomorrow.

Thanks again!

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.