talk and subscribe
base 24.02 ubuntu
jazzy ros2
check the version of ros2
echo $ROS_DISTRO
which ros2
1 Ctrl + Alt + T open the first terminal
2 source /opt/ros/jazzy/setup.bash
3 mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src
// create package in src workplace ,not in the root
4 creat python package
ros2 pkg create --build-type ament_python my_py_pubsub --dependencies rclpy std_msgs
5 dive into the package dic
cd ~/ros2_ws/src/my_py_pubsub
6
creat talker and listenser code file
cd ~/ros2_ws/src/my_py_pubsub/my_py_pubsub
touch talker.py listener.py
7
talker.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class TalkerNode(Node):
def __init__(self):
super().__init__('talker_node')
self.publisher_ = self.create_publisher(String, 'chatter', 10)
self.timer = self.create_timer(1.0, self.timer_callback)
self.count = 0
def timer_callback(self):
msg = String()
msg.data = f'Hello World: {self.count}'
self.publisher_.publish(msg)
self.get_logger().info(f'Publishing: "{msg.data}"')
self.count += 1
def main(args=None):
rclpy.init(args=args)
node = TalkerNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
8
talker.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class ListenerNode(Node):
def __init__(self):
super().__init__('listener_node')
self.subscription = self.create_subscription(
String,
'chatter',
self.listener_callback,
10
)
def listener_callback(self, msg):
self.get_logger().info(f'I heard: "{msg.data}"')
def main(args=None):
rclpy.init(args=args)
node = ListenerNode()
rclpy.spin(node)
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
9 in the first terminal
cd ~/ros2_ws
colcon build --packages-select my_py_pubsub
source ~/ros2_ws/install/setup.bash
ros2 run my_py_pubsub listener
10 in the second terminal
source /opt/ros/jazzy/setup.bash
source ~/ros2_ws/install/setup.bash
ros2 run my_py_pubsub talker
explain:
这个实验本质上做了什么?
先说结论。
我们刚刚做的事情,本质上是:
建了一个 ROS 2 工作空间
在这个工作空间里创建了一个 Python 类型的 ROS 2 包
在这个包里写了两个节点:
talker.py
listener.py
再通过 colcon build 让 ROS 2 识别这个包
最后通过 ros2 run 运行节点
所以,这不是“随便写了两个 Python 文件”,而是:
我们创建了一个最小的 ROS 2 Python 示例包,用来验证发布/订阅通信机制。
ROS 2 的思路是:
写 node → 放进 package → 放进 workspace → build → 用 ros2 run 运行
*workplace : ros2_ws/ *
以后你可以在这个 workspace 里放很多个 ROS 2 包,比如:
my_py_pubsub
my_robot_control
my_camera_pkg
src/ 是源码目录。
自己写的包,通常都放在这里。
所以常见的习惯就是:
mkdir -p ~/ros2_ws/src
src/ 下面的外层 my_py_pubsub/,
就是你的 ROS 2 包目录。
它的名字就是包名,所以以后你运行的时候会用到这个名字:
ros2 run my_py_pubsub talker
package.xml:这个包的身份证
package.xml 可以理解成 ROS 2 包的“身份证”或者“说明书”。
它通常会记录这些信息:
包名
版本
描述
作者 / 维护者
依赖项
setup.py:告诉系统“这个包怎么装、怎么跑”
setup.py 是 Python 包的安装配置文件。
它的作用包括:
声明 Python 模块
指定包名
配置可执行入口
告诉系统哪些脚本能被当成命令运行
其中最关键的一段,通常长这样:
entry_points={
'console_scripts': [
'talker = my_py_pubsub.talker:main',
'listener = my_py_pubsub.listener:main',
],
}
这段配置非常重要。
它的意思是:
当你执行:
ros2 run my_py_pubsub talker
ROS 2 实际上会去调用:
my_py_pubsub/talker.py
里面的:
main()
函数。
13. talker.py 和 listener.py 分别干嘛?
这两个就是你真正写的 ROS 2 节点代码。
talker.py
它是发布者节点,主要做三件事:
创建一个 publisher
定时生成消息
把消息发到 topic chatter
所以它负责“说话”。
listener.py
它是订阅者节点,主要做两件事:
创建一个 subscriber
收到 chatter 上的消息后打印出来
所以它负责“听话”。
这两个文件合起来,就是 ROS 2 最小的通信实验。
14. build/、install/、log/ 是什么?
这三个目录通常不是你手动创建的,
而是执行下面这个命令后自动生成的:
colcon build
它们分别代表不同阶段的构建结果。
build/
这里是编译过程中的中间文件。
可以理解成构建缓存和临时产物。
install/
这里是构建完成后的“安装结果”。
这个目录非常重要,因为构建完成后你通常要执行:
source ~/ros2_ws/install/setup.bash
这样系统才知道你自己写的包在哪里,才能用 ros2 run 找到它。
log/
这里是构建日志。
如果编译失败,很多时候可以来这里查问题。
所以这三个目录里,初学阶段你最需要理解的是:
install/ 很重要,因为它决定你的包能不能被 ROS 2 正确加载


Top comments (0)