Hello,
I made simple custom plugin to getting current distance from sensors, but when I want to use it in my program after installation, compiling fails with error:
undefined reference to `mavsdk::Distance::subscribe_current_distance(std::function<void (unsigned int)>)'
CMakeFiles/MAVLINK_avoiding.dir/main.cpp.o: In function `void __gnu_cxx::new_allocator<mavsdk::Distance>::construct<mavsdk::Distance, mavsdk::System&>(mavsdk::Distance*, mavsdk::System&)':
I tried defining subscribe_current_distance
in implementation files, but it would ended with failure in compiling MAVSDK (gcc complains about function being already defined in distance.cpp
)
What I should do?
plugin usage example ending in failure:
distance->subscribe_current_distance([](uint32_t currentDistance){
cout<<currentDistance<<endl;
});
distance.proto
syntax = "proto3";
//get distance from sensors
service DistanceService{
rpc SubscribeCurrentDistance(SubscribeCurrentDistanceRequest) returns(stream CurrentDistanceResponse){}
}
message SubscribeCurrentDistanceRequest{}
message CurrentDistanceResponse{
uint32 distance = 1;
}
distance.cpp:
// WARNING: THIS FILE IS AUTOGENERATED! As such, it should not be edited.
// Edits need to be made to the proto files
// (see https://github.com/mavlink/MAVSDK-Proto/blob/master/protos/distance/distance.proto)
#include <iomanip>
#include "distance_impl.h"
#include "plugins/distance/distance.h"
namespace mavsdk {
Distance::Distance(System& system) : PluginBase(), _impl{new DistanceImpl(system)} {}
Distance::~Distance() {}
void Distance::subscribe_current_distance(CurrentDistanceCallback callback)
{
_impl->current_distance_async(callback);
}
uint32_t
Distance::current_distance() const
{
return _impl->current_distance();
}
} // namespace mavsdk
distance.h
// WARNING: THIS FILE IS AUTOGENERATED! As such, it should not be edited.
// Edits need to be made to the proto files
// (see https://github.com/mavlink/MAVSDK-Proto/blob/master/protos/distance/distance.proto)
#pragma once
#include <array>
#include <cmath>
#include <functional>
#include <limits>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "plugin_base.h"
namespace mavsdk {
class System;
class DistanceImpl;
/**
* @brief get distance from sensors
*/
class Distance : public PluginBase {
public:
/**
* @brief Constructor. Creates the plugin for a specific System.
*
* The plugin is typically created as shown below:
*
* ```cpp
* auto distance = std::make_shared<Distance>(system);
* ```
*
* @param system The specific system associated with this plugin.
*/
explicit Distance(System& system);
/**
* @brief Destructor (internal use only).
*/
~Distance();
/**
* @brief Callback type for subscribe_current_distance.
*/
using CurrentDistanceCallback = std::function<void(uint32_t)>;
/**
* @brief
*/
void subscribe_current_distance(CurrentDistanceCallback callback);
/**
* @brief Poll for 'uint32_t' (blocking).
*
* @return One uint32_t update.
*/
uint32_t current_distance() const;
/**
* @brief Copy constructor (object is not copyable).
*/
Distance(const Distance&) = delete;
/**
* @brief Equality operator (object is not copyable).
*/
const Distance& operator=(const Distance&) = delete;
private:
/** @private Underlying implementation, set at instantiation */
std::unique_ptr<DistanceImpl> _impl;
};
} // namespace mavsdk
distance_impl.cpp:
#include "distance_impl.h"
namespace mavsdk {
DistanceImpl::DistanceImpl(System& system) : PluginImplBase(system)
{
_parent->register_plugin(this);
}
DistanceImpl::~DistanceImpl()
{
_parent->unregister_plugin(this);
}
void DistanceImpl::init() {
using namespace std::placeholders;
_parent->register_mavlink_message_handler(
MAVLINK_MSG_ID_DISTANCE_SENSOR,
std::bind(&DistanceImpl::process_distance_sensor,this,_1),
this);
}
void DistanceImpl::deinit() {
_parent->unregister_all_mavlink_message_handlers(this);
}
void DistanceImpl::enable() {}
void DistanceImpl::disable() {}
/*uint32_t Distance::current_distance() const {
return _impl->current_distance();
}
void Distance::subscribe_current_distance(CurrentDistanceCallback callback)
{
_impl->current_distance_async(callback);
}*/
uint32_t
DistanceImpl::current_distance() const
{
return _current_distance;
}
void DistanceImpl::process_distance_sensor(const mavlink_message_t& message){
uint32_t currentDistance;
currentDistance = mavlink_msg_distance_sensor_get_current_distance(&message);
set_current_distance(currentDistance);
if(_current_distance_subscription){
auto callback = _current_distance_subscription;
auto arg = current_distance();
_parent->call_user_callback([callback,arg](){callback(arg);});
}
}
void DistanceImpl::set_current_distance(uint32_t distance){
_current_distance = distance;
};
void DistanceImpl::current_distance_async(Distance::CurrentDistanceCallback &callback) {
_current_distance_subscription=callback;
}
} // namespace mavsdk
distance_impl.h:
#pragma once
#include "plugins/distance/distance.h"
#include "plugin_impl_base.h"
namespace mavsdk {
class DistanceImpl : public PluginImplBase {
public:
DistanceImpl(System& system);
~DistanceImpl();
void init() override;
void deinit() override;
void enable() override;
void disable() override;
void subscribe_current_distance(Distance::CurrentDistanceCallback callback);
uint32_t current_distance() const;
void current_distance_async(Distance::CurrentDistanceCallback& callback);
DistanceImpl(const DistanceImpl&)= delete;
DistanceImpl& operator=(const DistanceImpl&)= delete;
private:
void set_current_distance(uint32_t distance);
void process_distance_sensor(const mavlink_message_t& message);
std::atomic_uint32_t _current_distance {0};
Distance::CurrentDistanceCallback _current_distance_subscription{nullptr};
};
} // namespace mavsdk
Shouldn’t you remove that from distance_impl.h
, as it is not implemented in distance_impl.cpp
?
removing it didn’t fix undefined reference problem; uncommenting commented block
uint32_t Distance::current_distance() const {
return _impl->current_distance();
}
void Distance::subscribe_current_distance(CurrentDistanceCallback callback)
{
_impl->current_distance_async(callback);
}
in distance_impl.cpp ends with CMake error:
CMakeFiles/mavsdk_distance.dir/distance_impl.cpp.o: In function `mavsdk::Distance::current_distance() const':
/home/kris/MAVSDK/src/plugins/distance/distance_impl.cpp:32: multiple definition of `mavsdk::Distance::current_distance() const'
CMakeFiles/mavsdk_distance.dir/distance.cpp.o:/home/kris/MAVSDK/src/plugins/distance/distance.cpp:30: first defined here
CMakeFiles/mavsdk_distance.dir/distance_impl.cpp.o: In function `mavsdk::Distance::subscribe_current_distance(std::function<void (unsigned int)>)':
/home/kris/MAVSDK/src/plugins/distance/distance_impl.cpp:37: multiple definition of `mavsdk::Distance::subscribe_current_distance(std::function<void (unsigned int)>)'
CMakeFiles/mavsdk_distance.dir/distance.cpp.o:/home/kris/MAVSDK/src/plugins/distance/distance.cpp:21: first defined here
damn, I just forgot about updating CMake list xD