nav2_gps_waypoint_follower_demo:XML Parsing Error: XML or text declaration not at start of entity

对nav2_gps_waypoint_follower_demo中定义的urdf文件turtlebot3_waffle_gps.urdf,在launch时采用如下方式加载:

default_model_path = os.path.join(pkg_share, 'urdf/turtlebot3_waffle_gps.urdf')
launch.actions.DeclareLaunchArgument(name='model', default_value=default_model_path,
                                            description='Absolute path to robot urdf file'),

执行时提示:XML Parsing Error: XML or text declaration not at start of entity。

具体如下:

[ERROR] [launch]: Caught exception in launch (see debug for traceback): executed command failed. Command: xacro /home/tom/Tom/DockerContent/nav2_ws/install/nav2_gps_waypoint_follower_demo/share/nav2_gps_waypoint_follower_demo/urdf/turtlebot3_waffle_gps.urdf
Captured stderr output: XML parsing error: XML or text declaration not at start of entity: line 4, column 0

打开turtlebot3_waffle_gps.urdf文件看前几行的代码:

<!-- This is the same turtlebot urdf in nav2 with the following changes -->
<!-- 1. A link for the GPS sensor is added -->

<?xml version="1.0" ?>
<robot name="turtlebot3_waffle" xmlns:xacro="http://ros.org/wiki/xacro">
  <!-- <xacro:include filename="$(find turtlebot3_description)/urdf/common_properties.urdf"/>

根据错误提示,第4行xml的声明不在入口的开始(XML or text declaration not at start of entity: line 4, column 0),于是将前面的注释和空格都删掉,前面几行改为:

<?xml version="1.0" ?>
<robot name="turtlebot3_waffle" xmlns:xacro="http://ros.org/wiki/xacro">
  <!-- <xacro:include filename="$(find turtlebot3_description)/urdf/common_properties.urdf"/>

再次编译执行,就好了。

欢迎加入多源融合定位与控制技术讨论QQ群,群号:518859469

来自:上海代数律动技术有限公司

<think>我们正在处理一个C++编译错误。错误代码C1086表示我们尝试在一个const对象上调用一个非const成员函数。具体来说,对象类型为`const waypoint_follower::PurePursuitNode`,而成员函数`computecurvatureLookaheadDistance`没有被声明为const,因此不能在const对象上调用。 解决方案: 1. 将成员函数声明为const:如果该成员函数不修改对象的状态(即不修改任何非mutable成员变量),则可以将其声明为const。这样,它就可以在const对象上调用。 2. 移除对象的const限定:如果该函数确实需要修改对象,且当前对象不应该为const,那么可以移除对象声明时的const限定符。但要注意,如果对象本身应该是常量,则修改它违背了设计初衷。 3. 使用mutable成员:如果该函数只需要修改某些特定的、可以容忍在const函数中被修改的成员变量,则可以将这些成员变量声明为mutable,同时将函数声明为const。但这种方法需谨慎,因为它会破坏const的语义。 通常,首选方法是根据函数的实际行为来决定是否将其声明为const。 步骤: 假设我们有如下类定义: ```cpp namespace waypoint_follower { class PurePursuitNode { public: double computecurvatureLookaheadDistance(); // 非const成员函数 // ... }; } ``` 如果`computecurvatureLookaheadDistance`不会修改任何成员变量,则将其改为const成员函数: ```cpp namespace waypoint_follower { class PurePursuitNode { public: double computecurvatureLookaheadDistance() const; // 添加const限定 // ... }; } ``` 然后在实现中也要加上const: ```cpp double waypoint_follower::PurePursuitNode::computecurvatureLookaheadDistance() const { // 函数体 } ``` 如果该函数确实需要修改对象,而你又在一个const对象上调用,那么你需要重新审视设计:这个对象是否真的应该是const?如果不是,则去掉const限定;如果是,那么可能需要改变设计。 另一种情况:如果你有一个const引用或指针,但是你需要调用非const成员函数,那么你可能需要去除const(使用const_cast),但这通常是不推荐的做法,因为它可能导致未定义行为,除非原始对象本身是非const的。 因此,最佳实践是:如果函数在逻辑上不会改变对象状态,就将其声明为const。 例子: 假设我们有以下使用场景: ```cpp void someFunction(const waypoint_follower::PurePursuitNode& node) { double curvature = node.computecurvatureLookaheadDistance(); // 如果computecurvatureLookaheadDistance不是const,这里就会报错 } ``` 此时,将computecurvatureLookaheadDistance改为const成员函数是最合适的解决方案。 所以,请检查`computecurvatureLookaheadDistance`函数的实现,判断它是否可以安全地声明为const。如果可以,就在声明和定义处都加上const关键字。 如果错误发生在类外部,你无法修改类的定义(比如这个类来自第三方库),那么你可能需要: - 如果可能,不要使用const对象(或const引用)来调用这个函数。 - 或者,如果确定对象本身是非const的,只是通过const指针或引用来访问,那么可以使用const_cast去除const限定,但必须确保原始对象是非const的。 然而,修改自己的代码(将成员函数const化)通常是更安全且更好的做法。 注意:错误代码C1086可能是不同编译器或IDE给出的错误编号(例如,在Visual Studio中,这个错误可能是C2662,而C1086通常是无法打开文件)。但根据问题描述,我们推断这是一个常量性相关的错误。在常见的编译器中,这类错误通常为: - GCC/Clang: error: passing 'const X' as 'this' argument discards qualifiers - MSVC: error C2662: ... cannot convert 'this' pointer from 'const X' to 'X &' 因此,请根据实际编译器错误信息确认,但解决方案是一致的。 综上所述,解决步骤: 1. 检查`computecurvatureLookaheadDistance`函数是否需要修改对象。 2. 如果不需要,将其声明为const(包括头文件中的声明和实现文件中的定义)。 3. 如果需要,则考虑是否应该移除调用该函数的对象的const限定(可能重新设计),或者将对象改为非const。 通常,这个错误是由于const正确性没有遵守而导致的,所以修改函数为const是最直接的解决方式。 </think>### C/C++错误C1086:const对象调用非const成员函数的解决方案 在C++中,当对象被声明为`const`时(如`const waypoint_follower::PurePursuitNode`),只能调用被声明为`const`的成员函数。错误C1086表示您尝试在const对象上调用非const成员函数`computecurvatureLookaheadDistance`。 #### 根本原因分析 1. **const对象的限制**:Const对象只能调用const成员函数,保证对象状态不被修改 2. **函数签名不匹配**:`computecurvatureLookaheadDistance`未被声明为const函数 ```cpp class PurePursuitNode { public: // 错误:缺少const限定符 double computecurvatureLookaheadDistance(); // 正确:const成员函数 double safeMethod() const; }; ``` #### 解决方案 ##### 方案1:修改成员函数声明(推荐) 如果函数不会修改对象状态,将其声明为`const`: ```cpp class PurePursuitNode { public: // 添加const限定符 double computecurvatureLookaheadDistance() const; }; // 实现也需要修改 double PurePursuitNode::computecurvatureLookaheadDistance() const { // 函数实现(不能修改成员变量) } ``` ##### 方案2:移除对象const限定 如果函数确实需要修改对象状态,且当前上下文允许: ```cpp // 原始调用(错误) const PurePursuitNode node; node.computecurvatureLookaheadDistance(); // 修改为(移除const) PurePursuitNode node; node.computecurvatureLookaheadDistance(); ``` ##### 方案3:使用mutable成员变量 当函数需要修改特定内部状态但不影响逻辑const性时: ```cpp class PurePursuitNode { private: mutable double cache; // mutable允许const函数修改 public: double computecurvatureLookaheadDistance() const { cache = ...; // 允许修改mutable成员 } }; ``` ##### 方案4:const_cast(不推荐) 仅当确定对象实际是非const时使用(有风险): ```cpp const PurePursuitNode node; const_cast<PurePursuitNode&>(node).computecurvatureLookaheadDistance(); ``` #### 最佳实践 1. **遵循const正确性**:80%的成员函数应声明为const[^1] 2. **代码审查检查**:使用静态分析工具检测const不一致 3. **API设计原则**:对不修改对象状态的函数添加const限定符 4. **编译器选项**:开启`-Werror=const`警告(GCC/Clang) > 通过适当使用const限定符,可以提高代码安全性和可读性,同时启用更多编译器优化[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值