Telemetry plugin - undefined reference error

Hello,

I’m hitting an error with the Telemetry plugin that I can’t seem to make my way through. It looks similar to the issue here, but the solution to that issue is no longer applicable since one only needs to link the MAVSDK::mavsdk library to the final executable for current versions of MAVSDK.

Essentially, when I compile my code, I receive a linking error back that states: “undefined reference to `mavsdk::Telemetry::Telemetry(mavsdk::Telemetry const&)’”

My CMakeLists file contains the following information:

cmake_minimum_required(VERSION 3.8)
project(uavrt_connection)

find_package(MAVSDK REQUIRED)

include_directories(include)

# ClassA.so
add_library(ClassA SHARED
 src/ClassA.cpp)
ament_target_dependencies(ClassA
 MAVSDK)

# ClassB.so
add_library(ClassB SHARED
 src/ClassB.cpp)
ament_target_dependencies(ClassB
 MAVSDK)

add_executable(main
 src/main.cpp)

target_link_libraries(main
 MAVSDK::mavsdk)

install(TARGETS
 ClassA
 ClassB
 ARCHIVE DESTINATION lib
 LIBRARY DESTINATION lib
 RUNTIME DESTINATION bin)

install(TARGETS
 main
 DESTINATION lib/${PROJECT_NAME})

A bare-bones example of the code where the error occurs:

ClassA.cpp

// C++ standard library headers
#include <chrono>
#include <functional>
#include <memory>
#include <thread>

namespace example 
{
ClassA::ClassA()
{
mavsdk.add_udp_connection("udp://:14540");

while (mavsdk.systems().size() == 0)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}

GetSystem();
TelemetryCallback(); 
}

void ClassA::GetSystem() : ClassBObject()
{
	if (mavsdk.systems().size() == 1)
	{
		system_ = serial_mavsdk.systems().at(0);
		connection_status_ = true;
	}
}

void ClassA::TelemetryCallback()
{
	if (connection_status_ == true)
	{
		mavsdk::Telemetry mavsdk_telemetry = mavsdk::Telemetry(system_);

		ClassBObject.RefreshTelemetry(mavsdk_telemetry); // <--- This line causes the error. 
	}
}
}  // namespace example

ClassA.hpp

// MAVSDK header files
#include "mavsdk/mavsdk.h"
#include "mavsdk/system.h"
#include "mavsdk/plugins/telemetry/telemetry.h"

namespace example 
{

class ClassA
{
public:

private:
GetSystem();
TelemetryCallback(); 

mavsdk::Mavsdk mavsdk;

std::shared_ptr<mavsdk::System> system_;
bool connection_status_; 

ClassB ClassBObject;
};

}  // namespace example 

The public function “RefreshTelemetry(mavsdk_telemetry)” is within a separate ClassB.cpp and ClassB.hpp file. The structure is similar to ClassA.cpp and ClassA.hpp and contains the same include statements. It is linked in the CMakeLists file the same way that ClassA is linked.

The repo that houses this code is currently private, so I can’t link it directly. If the example code I provided above is lacking, please let me know.

Two things that stood out while debugging:

  • If I change mavsdk::Telemetry mavsdk_telemetry = mavsdk::Telemetry(system_); to std::shared_ptr<mavsdk::Telemetry> mavsdk_telemetry = std::make_shared<mavsdk::Telemetry>(system_); (and the corresponding function headers in ClassA and ClassB), then the code will compile. However, when I run it and attempt to retrieve values, all I get back are nan values. I’ve ran the code example code here and I did not have issues retrieving altitude values with a Px4 gazebo SITL.
  • If I remove this line ClassBObject.RefreshTelemetry(mavsdk_telemetry);, then I am able to compile. Again, if I make the change in the previous bullet, then this line doesn’t to be removed and I can compile.

The compiling is being done on a Ubuntu 20.04 LTS machine using gcc version 9.4.0 and CMake version 3.16.3.

I appreciate any help,
Matt

Update in case someone sees this: I ended up refactoring my code so that the following lines…

mavsdk::Telemetry mavsdk_telemetry = mavsdk::Telemetry(system_);

ClassBObject.RefreshTelemetry(mavsdk_telemetry);

…were no longer necessary. I instead went with the more common approach outlined in most of MAVSDK’s example code and integration tests.

I’m still not sure what the issue was.