C++ нет соответствующей функции для вызова `LogBlock<CrazyflieROS:: logMotor>`
Я пытаюсь изменить уже существующий пакет ROS, добавляя и удаляя некоторые вещи в папке crazyflie_driver. Я собираю с catkin_make
а у меня ROS Kinetic 16.04. Часть, которую я на самом деле модифицирую в сценарии crazyflie_server C++, такова:
private:
struct logImu {
float acc_x;
float acc_y;
float acc_z;
float gyro_x;
float gyro_y;
float gyro_z;
} атрибут((упакованный));
private:
struct logMotor {
int m1;
int m2;
int m3;
int m4;
} __attribute__((packed));
void onImuData(uint32_t time_in_ms, logImu* data) {
if (m_enable_logging_imu) {
sensor_msgs::Imu msg;
if (m_use_ros_time) {
msg.header.stamp = ros::Time::now();
} else {
msg.header.stamp = ros::Time(time_in_ms / 1000.0);
}
msg.header.frame_id = m_tf_prefix + "/base_link";
msg.orientation_covariance[0] = -1;
//new
msg.orientation.x = cos(data->gyro_z/2)*cos(data->gyro_y/2)*cos(data->gyro_x/2) + sin(data->gyro_z/2)*sin(data->gyro_y/2)*sin(data->gyro_x/2);
msg.orientation.y = sin(data->gyro_z/2)*cos(data->gyro_y/2)*cos(data->gyro_x/2) - cos(data->gyro_z/2)*sin(data->gyro_y/2)*sin(data->gyro_x/2);
msg.orientation.z = cos(data->gyro_z/2)*sin(data->gyro_y/2)*cos(data->gyro_x/2) + sin(data->gyro_z/2)*cos(data->gyro_y/2)*sin(data->gyro_x/2);
msg.orientation.w = cos(data->gyro_z/2)*cos(data->gyro_y/2)*sin(data->gyro_x/2) - sin(data->gyro_z/2)*sin(data->gyro_y/2)*cos(data->gyro_x/2);
//endnew
// measured in deg/s; need to convert to rad/s
msg.angular_velocity.x = degToRad(data->gyro_x);
msg.angular_velocity.y = degToRad(data->gyro_y);
msg.angular_velocity.z = degToRad(data->gyro_z);
// measured in mG; need to convert to m/s^2
msg.linear_acceleration.x = data->acc_x * 9.81;
msg.linear_acceleration.y = data->acc_y * 9.81;
msg.linear_acceleration.z = data->acc_z * 9.81;
m_pubImu.publish(msg);
}
}
void onMotorData(logMotor* data) {
std_msgs::Int32MultiArray array;
array.data.clear();
array.data.push_back(data->m1);
array.data.push_back(data->m2);
array.data.push_back(data->m3);
array.data.push_back(data->m4);
m_pubMotors.publish(array);
}
std::function<void(uint32_t, logImu*)> cb = std::bind(&CrazyflieROS::onImuData, this, std::placeholders::_1,std::placeholders::_2);
logBlockImu.reset(new LogBlock<logImu>(
&m_cf,{
{"acc", "x"},
{"acc", "y"},
{"acc", "z"},
{"gyro", "x"},
{"gyro", "y"},
{"gyro", "z"},
}, cb));
logBlockImu->start(1); // 10ms
std::function<void(logMotor*)> cbmotor = std::bind(&CrazyflieROS::**onMotorData**, this, std::placeholders::_1);
logBlockMotor.reset(new LogBlock<logMotor>(
&m_cf,{
{"motor", "m1"},
{"motor", "m2"},
{"motor", "m3"},
{"motor", "m4"},
}, cbmotor));
logBlockMotor->start(1); // 10ms
}
Моя проблема в том, что когда я пытаюсь скомпилировать с этой частью кода:
>logBlockMotor.reset(new LogBlock<logMotor>(
&m_cf,{
{"motor", "m1"},
{"motor", "m2"},
{"motor", "m3"},
{"motor", "m4"},
}, cbmotor));
это дает мне не подходящую функцию для вызова LogBlock<CrazyflieROS::logMotor>
/home/bitcraze/catkin_ws/src/crazyflie_ros/crazyflie_driver/src/crazyflie_server.cpp: In member function ‘void CrazyflieROS::run()’:
/home/bitcraze/catkin_ws/src/crazyflie_ros/crazyflie_driver/src/crazyflie_server.cpp:530:9: error: no matching function for call to ‘LogBlock<CrazyflieROS::logMotor>::LogBlock(Crazyflie*, <brace-enclosed initializer list>, std::function<void(unsigned int, CrazyflieROS::logImu*)>&)’
}, cb));
^
In file included from /home/bitcraze/catkin_ws/src/crazyflie_ros/crazyflie_driver/src/crazyflie_server.cpp:50:0:
/home/bitcraze/catkin_ws/src/crazyflie_ros/crazyflie_cpp/include/crazyflie_cpp/Crazyflie.h:462:3: note: candidate: LogBlock<T>::LogBlock(Crazyflie*, std::__cxx11::list<std::pair<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> > >, std::function<void(unsigned int, T*)>&) [with T = CrazyflieROS::logMotor]
LogBlock(
^
/home/bitcraze/catkin_ws/src/crazyflie_ros/crazyflie_cpp/include/crazyflie_cpp/Crazyflie.h:462:3: note: no known conversion for argument 3 from ‘std::function<void(unsigned int, CrazyflieROS::logImu*)>’ to ‘std::function<void(unsigned int, CrazyflieROS::logMotor*)>&’
/home/bitcraze/catkin_ws/src/crazyflie_ros/crazyflie_cpp/include/crazyflie_cpp/Crazyflie.h:459:7: note: candidate: LogBlock<CrazyflieROS::logMotor>::LogBlock(const LogBlock<CrazyflieROS::logMotor>&)
class LogBlock
^
/home/bitcraze/catkin_ws/src/crazyflie_ros/crazyflie_cpp/include/crazyflie_cpp/Crazyflie.h:459:7: note: candidate expects 1 argument, 3 provided
crazyflie_ros/crazyflie_driver/CMakeFiles/crazyflie_server.dir/build.make:62: recipe for target 'crazyflie_ros/crazyflie_driver/CMakeFiles/crazyflie_server.dir/src/crazyflie_server.cpp.o' failed
make[2]: *** [crazyflie_ros/crazyflie_driver/CMakeFiles/crazyflie_server.dir/src/crazyflie_server.cpp.o] Error 1
CMakeFiles/Makefile2:2995: recipe for target 'crazyflie_ros/crazyflie_driver/CMakeFiles/crazyflie_server.dir/all' failed
make[1]: *** [crazyflie_ros/crazyflie_driver/CMakeFiles/crazyflie_server.dir/all] Error 2
Makefile:138: recipe for target 'all' failed
make: *** [all] Error 2
Invoking "make -j1 -l1" failed
И это часть файла LogBlock.h:
namespace crazyflie_driver
{
template <class ContainerAllocator>
struct LogBlock_
{
typedef LogBlock_<ContainerAllocator> Type;
LogBlock_()
: topic_name()
, frequency(0)
, variables() {
}
LogBlock_(const ContainerAllocator& _alloc)
: topic_name(_alloc)
, frequency(0)
, variables(_alloc) {
(void)_alloc;
}
typedef std::basic_string<char, std::char_traits<char>, typename ContainerAllocator::template rebind<char>::other > _topic_name_type;
_topic_name_type topic_name;
typedef int16_t _frequency_type;
_frequency_type frequency;
typedef std::vector<std::basic_string<char, std::char_traits<char>, typename ContainerAllocator::template rebind<char>::other > , typename ContainerAllocator::template rebind<std::basic_string<char, std::char_traits<char>, typename ContainerAllocator::template rebind<char>::other > >::other > _variables_type;
_variables_type variables;
typedef boost::shared_ptr< ::crazyflie_driver::LogBlock_<ContainerAllocator> > Ptr;
typedef boost::shared_ptr< ::crazyflie_driver::LogBlock_<ContainerAllocator> const> ConstPtr;
}; // struct LogBlock_
Я не понимаю, что я делаю неправильно, потому что, если я оставлю в коде материал onImuData, он отлично скомпилируется. Как только я добавляю эту часть кода, появляется ошибка компилятора.
Может кто-нибудь мне помочь? Я попытался также посмотреть на файл CMake.txt, но кажется, что он включает в себя каталоги, и нет ничего плохого:
cmake_minimum_required(VERSION 2.8.3)
project(crazyflie_driver)
find_package(catkin REQUIRED COMPONENTS
message_generation
std_msgs
tf
crazyflie_cpp
)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_service_files(
FILES
AddCrazyflie.srv
GoTo.srv
Land.srv
RemoveCrazyflie.srv
SetGroupMask.srv
StartTrajectory.srv
Stop.srv
Takeoff.srv
UpdateParams.srv
UploadTrajectory.srv
sendPacket.srv
)
add_message_files(
FILES
LogBlock.msg
GenericLogData.msg
FullState.msg
TrajectoryPolynomialPiece.msg
crtpPacket.msg
Hover.msg
Position.msg
)
## Generate added messages and services with any dependencies listed here
generate_messages(
DEPENDENCIES
std_msgs
geometry_msgs
)
catkin_package(
CATKIN_DEPENDS
message_runtime
std_msgs
tf
crazyflie_cpp
)
###########
## Build ##
###########
include_directories(
${catkin_INCLUDE_DIRS}
)
## Declare a cpp executable
add_executable(crazyflie_server
src/crazyflie_server.cpp
)
add_dependencies(crazyflie_server
crazyflie_driver_generate_messages_cpp
)
## Specify libraries to link a library or executable target against
target_link_libraries(crazyflie_server
${catkin_LIBRARIES}
)
## Declare a cpp executable
add_executable(crazyflie_add
src/crazyflie_add.cpp
)
add_dependencies(crazyflie_add
crazyflie_driver_generate_messages_cpp
)
target_link_libraries(crazyflie_add
${catkin_LIBRARIES}
)
Заранее спасибо!
1 ответ
Вы создаете
std::function<void(logMotor*)> cbmotor = ...
а затем передать его конструктору, который ожидает
std::function<void(uint32_t, T*)>&
(где T
предположительно logMotor
). Эти два типа не совместимы. Это то, что я прочитал в вашем источнике.
Сообщение об ошибке, с другой стороны, говорит
нет известного преобразования для аргумента 3 из
‘std::function<void(unsigned int, CrazyflieROS::logImu*)>’
в‘std::function<void(unsigned int, CrazyflieROS::logMotor*)>&’
что означает, что вы создаете logImu
ориентированный обратный вызов и пытается передать его logMotor
ориентированный параметр. Вы, вероятно, показывает сообщение об ошибке из файла, отличного от того, который вы опубликовали в качестве источника.
В любом случае вам нужно передать правильный тип обратного вызова.
На несколько не связанной ноте:
LogBlock(
Crazyflie* cf,
std::list<std::pair<std::string, std::string> > variables,
std::function<void(uint32_t, T*)>& callback)
ошибка в пакете, который вы пытаетесь использовать. Нет смысла иметь неконстантную ссылку std::function
аргумент, а затем сразу скопировать его в переменную-член. Это излишне ограничивает использование конструктора только с неконстантными аргументами lvalue. Например, вы можете сделать
std::function<void(uint32_t, logImu*)> cb = std::bind(...);
new LogBlock<logImu>(..., ..., cb)
но вы не можете сделать напрямую
new LogBlock<logImu>(..., ..., std::bind (...))
Конструктор должен иметь ссылочный параметр const и опционально иметь перегрузку с ссылочным параметром rvalue.
Функция также принимает std::list
по значению, что также не имеет смысла.