节点
每个节点都是执行某项功能进程的可执行文件
每个节点都有唯一的命名
命令行进入工作区文件夹,使用$ colcon build命令编译(之前编译过不需要重复编译)此步执行需保证src目录下仅有一个文件夹,否则报错
$ ros2 run learning_node node_helloworld 此步运行learning_node功能包中node_helloworld节点
节点编写-python
import rclpy #ros2 python接口库
from rclpy.node import Node #ros2 节点类
def main(args=None):
rcply.init(args=args) #初始化ros2的python接口,写死
nodea=Node("node_helloworld") #创建一个节点接口的实现类,参数为节点名字
while(rclpy.ok()): #ros2正常运行
node.get_logger().info("Hello World") # ROS2日志输出
time.sleep(0.5)
rclpy.spin(nodea) #此段为等待节点类终止,在这里删除并不会造成影响,具体原因及其用途会在话题中得到解答
node.destroy_node() #在ros2停止运行后,销毁节点对象,释放内存
rclpy.shutdown() #关闭ros2
python配置程序入口
此处需要在功能包中配置程序入口:
setup.py中:
entry_points={
'console_scripts': [
'node_helloworld = learning_node.node_helloworld:main',
],
},
将learning_node功能包里的node_helloworld程序的main函数赋值给名为node_helloworld的节点
注意这里在执行之前需要在根目录使用$ colcon_build命令重新编译(python不需要编译,但ros2需要)
python面向对象编程
显然,上面的代码是面向过程编程。
面向对象编程可以讲上述代码改成以下形式:
class helloworld(Node):
def __init__(self,name):
super().__init__(name)
while(rclpy.ok())
self.get_logger.info("Helloworld!")
time.sleep(0.5)
def main(args=None)
rclpy.init(args=args)
a=helloworld("ThisIsAHelloworldClass")
a.destroy_node()
rclpy.shutdown()
这段代码中,我们首先启动了rclpy并对其进行初始化
然后创建了一个helloworld类的实例化对象a。helloworld类为进行发送helloworld任务的执行类,它的构造函数__init__中,先使用super()函数调用父类中的初始化函数,然后在确认rclpy正常运行的情况下反复执行输出文本并等待的任务。
实例化对象a在被创建时调用构造函数,进行输出操作,当执行完毕后调用a的删除节点函数,最后调用rclpy类中的shutdo函数结束流程。
面向对象编程可以降低函数的耦合性,增强可扩展性。
注意:python写出的代码在进行编译后会储存在工作区/install/#{功能包名称}/lib中,其中python3.1/site-packages/存储的是代码,python3.10中存储节点的具体操作