You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

g++编译Orocos KDL C++机器人运动学代码遇链接错误求助

Orocos KDL链接错误:未定义KDL::Chain构造/析构函数

问题背景

在Kubuntu系统中从官网下载Orocos KDL C++库源码并编译安装,文件已部署到/usr/local/include和/usr/local/lib目录。但编译基础运动学链示例时,Eigen代码可正常编译,一旦使用KDL功能就出现链接错误,仅实例化空KDL::Chain对象就报错。

错误信息

/usr/bin/ld: /tmp/ccb58mLs.o: en la función `main':
edgarcpptest.cpp:(.text+0x11a): referencia a `KDL::Chain::Chain()' sin definir
/usr/bin/ld: edgarcpptest.cpp:(.text+0x126): referencia a `KDL::Chain::~Chain()' sin definir
collect2: error: ld returned 1 exit status

测试代码

#include <kdl/chain.hpp>
#include <kdl/chainfksolver.hpp>
#include <kdl/frames.hpp>
#include <kdl/frames_io.hpp>
#include <kdl/chainfksolverpos_recursive.hpp>
#include <iostream>
#include <Eigen/Dense>
#include <kdl/joint.hpp>
#include <kdl/segment.hpp>
int main(int argc, char *argv[])
{
    Eigen::MatrixXd a(4,4);
    a(0,0)=12;
    a(1,0)=13;
    a(0,1)=14;
    a(1,1)=15;
    std::cout << a << std::endl;
    Eigen::VectorXd v1(10);
    KDL::Chain chain;
    //chain.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotZ),KDL::Frame(KDL::Vector(0.0,0.0,1.20))));
    /*chain.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotX),KDL::Frame(KDL::Vector(0.0,0.0,0.480))));*/
    /*chain.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotX),KDL::Frame(KDL::Vector(0.0,0.0,0.645))));*/
    /*chain.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotZ)));*/
    /*chain.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotX),KDL::Frame(KDL::Vector(0.0,0.0,0.5))));*/
    /*chain.addSegment(KDL::Segment(KDL::Joint(KDL::Joint::RotZ)));*/
    
    /*KDL::ChainFkSolverPos_recursive fksolver= KDL::ChainFkSolverPos_recursive(chain);*/
    /*unsigned int nj= chain.getNrOfJoints();*/
    /*std::cout << "Numero de articulaciones:%d" << nj << std::endl;*/
}

编译命令

sudo g++ edgarcpptest.cpp -L /usr/local/lib/ -I /usr/local/include/ -I /usr/include/  -o edgartestcpp

已安装文件清单

/usr/local/share/orocos_kdl/cmake/FindEigen3.cmake
/usr/local/share/orocos_kdl/cmake/orocos_kdl-config.cmake
/usr/local/share/orocos_kdl/cmake/orocos_kdl-config-version.cmake
/usr/local/share/orocos_kdl/cmake/OrocosKDLTargets.cmake
/usr/local/share/orocos_kdl/cmake/OrocosKDLTargets-release.cmake
/usr/local/lib/pkgconfig/orocos-kdl.pc
/usr/local/lib/pkgconfig/orocos_kdl.pc
/usr/local/share/doc/liborocos-kdl/kdl.tag
/usr/local/lib/liborocos-kdl.so.1.5.1
/usr/local/lib/liborocos-kdl.so.1.5
/usr/local/lib/liborocos-kdl.so
/usr/local/include/kdl/articulatedbodyinertia.hpp
/usr/local/include/kdl/chain.hpp
/usr/local/include/kdl/chaindynparam.hpp
/usr/local/include/kdl/chainexternalwrenchestimator.hpp
/usr/local/include/kdl/chainfdsolver.hpp
/usr/local/include/kdl/chainfdsolver_recursive_newton_euler.hpp
/usr/local/include/kdl/chainfksolver.hpp
/usr/local/include/kdl/chainfksolverpos_recursive.hpp
/usr/local/include/kdl/chainfksolvervel_recursive.hpp
/usr/local/include/kdl/chainhdsolver_vereshchagin.hpp
/usr/local/include/kdl/chainidsolver.hpp
/usr/local/include/kdl/chainidsolver_recursive_newton_euler.hpp
/usr/local/include/kdl/chainidsolver_vereshchagin.hpp
/usr/local/include/kdl/chainiksolver.hpp
/usr/local/include/kdl/chainiksolverpos_lma.hpp
/usr/local/include/kdl/chainiksolverpos_nr.hpp
/usr/local/include/kdl/chainiksolverpos_nr_jl.hpp
/usr/local/include/kdl/chainiksolvervel_pinv.hpp
/usr/local/include/kdl/chainiksolvervel_pinv_givens.hpp
/usr/local/include/kdl/chainiksolvervel_pinv_nso.hpp
/usr/local/include/kdl/chainiksolvervel_wdls.hpp
/usr/local/include/kdl/chainjnttojacdotsolver.hpp
/usr/local/include/kdl/chainjnttojacsolver.hpp
/usr/local/include/kdl/frameacc.hpp
/usr/local/include/kdl/frameacc.inl
/usr/local/include/kdl/frameacc_io.hpp
/usr/local/include/kdl/frames.hpp
/usr/local/include/kdl/frames.inl
/usr/local/include/kdl/frames_io.hpp
/usr/local/include/kdl/framevel.hpp
/usr/local/include/kdl/framevel.inl
/usr/local/include/kdl/framevel_io.hpp
/usr/local/include/kdl/jacobian.hpp
/usr/local/include/kdl/jntarray.hpp
/usr/local/include/kdl/jntarrayacc.hpp
/usr/local/include/kdl/jntarrayvel.hpp
/usr/local/include/kdl/jntspaceinertiamatrix.hpp
/usr/local/include/kdl/joint.hpp
/usr/local/include/kdl/kdl.hpp
/usr/local/include/kdl/kinfam.hpp
/usr/local/include/kdl/kinfam_io.hpp
/usr/local/include/kdl/motion.hpp
/usr/local/include/kdl/path.hpp
/usr/local/include/kdl/path_circle.hpp
/usr/local/include/kdl/path_composite.hpp
/usr/local/include/kdl/path_cyclic_closed.hpp
/usr/local/include/kdl/path_line.hpp
/usr/local/include/kdl/path_point.hpp
/usr/local/include/kdl/path_roundedcomposite.hpp
/usr/local/include/kdl/rigidbodyinertia.hpp
/usr/local/include/kdl/rotational_interpolation.hpp
/usr/local/include/kdl/rotational_interpolation_sa.hpp
/usr/local/include/kdl/rotationalinertia.hpp
/usr/local/include/kdl/segment.hpp
/usr/local/include/kdl/solveri.hpp
/usr/local/include/kdl/stiffness.hpp
/usr/local/include/kdl/trajectory.hpp
/usr/local/include/kdl/trajectory_composite.hpp
/usr/local/include/kdl/trajectory_segment.hpp
/usr/local/include/kdl/trajectory_stationary.hpp
/usr/local/include/kdl/tree.hpp
/usr/local/include/kdl/treefksolver.hpp
/usr/local/include/kdl/treefksolverpos_recursive.hpp
/usr/local/include/kdl/treeidsolver.hpp
/usr/local/include/kdl/treeidsolver_recursive_newton_euler.hpp
/usr/local/include/kdl/treeiksolver.hpp
/usr/local/include/kdl/treeiksolverpos_nr_jl.hpp
/usr/local/include/kdl/treeiksolverpos_online.hpp
/usr/local/include/kdl/treeiksolvervel_wdls.hpp
/usr/local/include/kdl/treejnttojacsolver.hpp
/usr/local/include/kdl/velocityprofile.hpp
/usr/local/include/kdl/velocityprofile_dirac.hpp
/usr/local/include/kdl/velocityprofile_rect.hpp
/usr/local/include/kdl/velocityprofile_spline.hpp
/usr/local/include/kdl/velocityprofile_trap.hpp
/usr/local/include/kdl/velocityprofile_traphalf.hpp
/usr/local/include/kdl/config.h
/usr/local/include/kdl/utilities/error.h
/usr/local/include/kdl/utilities/error_stack.h
/usr/local/include/kdl/utilities/hash_combine.h
/usr/local/include/kdl/utilities/kdl-config.h
/usr/local/include/kdl/utilities/ldl_solver_eigen.hpp
/usr/local/include/kdl/utilities/rall1d.h
/usr/local/include/kdl/utilities/rall1d_io.h
/usr/local/include/kdl/utilities/rall2d.h
/usr/local/include/kdl/utilities/rall2d_io.h
/usr/local/include/kdl/utilities/rallNd.h
/usr/local/include/kdl/utilities/scoped_ptr.hpp
/usr/local/include/kdl/utilities/svd_HH.hpp
/usr/local/include/kdl/utilities/svd_eigen_HH.hpp
/usr/local/include/kdl/utilities/svd_eigen_Macie.hpp
/usr/local/include/kdl/utilities/traits.h
/usr/local/include/kdl/utilities/utility.h
/usr/local/include/kdl/utilities/utility_io.h

解决方案

这是链接阶段未找到Orocos KDL库的典型问题——你的编译命令仅指定了库搜索路径-L,但没有明确告诉编译器要链接liborocos-kdl.so库。以下是三种解决方式:

1. 直接在编译命令中添加库链接参数

修改编译命令,加入-lorocos-kdl(规则是去掉库文件名的lib前缀和.so后缀):

g++ edgarcpptest.cpp -L /usr/local/lib/ -I /usr/local/include/ -lorocos-kdl -o edgartestcpp

提示:编译普通程序不需要sudo,仅当需要将可执行文件安装到系统目录时才需要管理员权限。

2. 用pkg-config自动获取编译参数

系统中已存在/usr/local/lib/pkgconfig/orocos-kdl.pc配置文件,可通过pkg-config自动生成编译和链接参数,简化命令:

g++ edgarcpptest.cpp $(pkg-config --cflags --libs orocos-kdl) -o edgartestcpp

如果pkg-config提示找不到orocos-kdl,先执行以下命令更新环境变量:

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH

3. 使用CMake构建(推荐用于复杂项目)

创建CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.10)
project(edgartestcpp)

# 查找Orocos KDL库
find_package(OrocosKDL REQUIRED)

# 添加可执行文件
add_executable(edgartestcpp edgarcpptest.cpp)

# 链接Orocos KDL库
target_link_libraries(edgartestcpp ${OROCOS_KDL_LIBRARIES})

然后执行编译:

mkdir -p build && cd build
cmake ..
make

验证链接结果

编译完成后,可通过以下命令检查可执行文件是否正确链接了Orocos KDL库:

ldd edgartestcpp | grep orocos-kdl

若输出类似liborocos-kdl.so.1.5 => /usr/local/lib/liborocos-kdl.so.1.5,说明链接成功。

内容的提问来源于stack exchange,提问作者Edgar Robles Najar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 03:55:25