零之前言
就我而言,我觉得对于使用ROS的人来说,使用C++的人多于使用Python的人吧。Python和C++编写的节点有很大的差异。
虽说Python带来了许多便利性的同时,也带来了许多非兼容性。下面我详细说:
一.编译
Python是一种解释语言,而C++是一种编译语言。就如同我们存放的位置所说,.py文件是放在/script文件下,就说明了其是动态的,不需要编译,我们修改了.py的内容后,可以直接运行;C++则是调用其编译后的产物,也就是说,我们运行的时候,根本不需要它的.cpp这样的源码,所以我们在修改了.cpp后,需要重新catkin_make
二.依赖
我们创建的消息、服务是需要通过庞大的make系统调用一系列东西来生成,所以在两者Python与C++编写CMakeList.txt生成消息文件,服务文件的时候,这些代码基本上是一样的,所以都需要编写、修改:find_package、add_message_files、add_service_files、generate_messages、catkin_package等之类的内容。
而C++为了生成可执行文件,我们还得添加add_executable、target_link_libraries这样的内容。
而Python就不一样了,直接使用rosrun 包名 xxx.py即可运行节点,亦或着在目录下python xxx.py
三.运行
C++是基于编译的,只要我们弄好了编译链,编译成可执行程序,就OK搞定了。但是Python是一种脚本化的动态语言,同一个代码在不同的解释器上有不同的效果,我们得控制Python版本,路径,环境……
就比如使用Python编写节点,你需要确保系统Python解释器为2.7,且需要注释掉Anaconda这样的发行版
编写Python的时候将默认解释器确保为2.7的方法见此帖(Ubuntu是默认2.7的,除非你修改过)在Linux/Ubuntu中修改Python默认版本。
注:在ROS Melodic版本下,我发现了好像可以使用3+版本的解释器,但我没有验证,这是代码的蛛丝马迹:

四.编写
虽然ROS在为我们提供的ros.h与rospy尽可能的将两者的区别最小化,是得编程逻辑能够一致,但是由于两者编译/运行的方式不同,还是不得不出现一些差异。
这里会整理C++与Python的编写时的差异,也会持续更新:
1.头文件/包名
先说它俩位置:
- C++头文件的位置在
/devel/include/功能包名/里 - Python的生成的文件在
/devel/lib/python2.7/dist-packages/功能包名/里
它俩结构也可能不同,就如我们创建的服务为例:
- C++的服务一次创建了三个,
add.h、addRequest.h、addResponse.h。虽然是三个,但也存在这包含关系,我们可以直接include<add.h> - Python对于同一个服务就只有两个文件,
_add.py、__init__.py,且核心都放在_add.py里.
因为Python和C++的面向对象有着差异,所以我们编写的时候,搞混了两种方式如何调用消息或服务的话,推荐过来看看它的源码。
致此,也说明了为什么要在编写节点代码的时候,先catkin_make一下的原因:为了方便我们写程序的时候,可以以代码的形式查看这些消息、服务文件。
2.spin与spinOnce
在C++里,提供了spin与spinOnce。两者的区别就是:
spin运行后,直接阻塞在这里,一直检查回调函数状态,不会执行后面的代码,直到节点销毁。spinOnce是检查一下回调函数状态,若回调了,就先处理,处理完后继续执行后面的代码,需要配合ros::ok()来进行循环操作。
在Python里,却只提供了spin函数,那么我们不想让他阻塞的话,只有为我们的spin函数整一个线程:
import threading
def goaway():
rospy.spin()
if __name__ == "__main__":
spin_thread = threading.Thread(target = goaway)
spin_stread.start()
最后
以上就是暴躁毛巾最近收集整理的关于ROS学习记录7——Python与C++编写节点的不同零之前言一.编译二.依赖三.运行四.编写的全部内容,更多相关ROS学习记录7——Python与C++编写节点内容请搜索靠谱客的其他文章。
发表评论 取消回复