概述
零之前言
就我而言,我觉得对于使用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++编写节点的不同零之前言一.编译二.依赖三.运行四.编写所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复