Lab: Introduction to ROS2
Today's Lesson
Practice :
Create a package
A package is a container for your ROS 2 code.
$ mkdir -p ros2_ws/src
$ cd ros2_ws/src
$ ros2 pkg create --build-type ament_python iml_buche_test
Create a node
Create
start.py
and place it in
ros2_ws/src/iml_buche_test/iml_buche_test/
start.py
import rclpy
from rclpy.node import Node
def main(args=None):
# initialize ROS communications
rclpy.init(args=args)
# create the node
node = Node('start_node')
# start ROS2 publishers, subscribers, services, get parameters, etc
rclpy.spin(node)
# When you request to kill the node
rclpy.shutdown()
if __name__ == '__main__':
main()
Add an entry point in the
setup.py
setup.py
#...
entry_points={
'console_scripts': [
'test_python_node = iml_buche_test.start:main'
],
...
Note:
test_python_node will be the name of the executable,
start is the name of the Python file
my_node_name is the name of the node (written in the Python file).
package.xml
Add
rclpy dependency
ament_python
...
rclpy
# Compile your package
$ cd ros2_ws
$ colcon build
# source your ROS2 workspace
$ . install/setup.bash
# run
$ ros2 run iml_buche_test test_python_node
Manipulate node
# change the node’s name from “my_node” to “another_node”
$ ros2 run iml_buche_test test_python_node --ros-args -r __node:=another_node
# dans un autre terminal
$ . install/setup.bash # source
$ ros2 run iml_buche_test test_python_node
# it could be nice to be able to see what’s going on
$ ros2 node list
# Get more details about a Node
$ ros2 node info /another_node
Create another node
Create
anotherNode.py
and place it in
ros2_ws/src/iml_buche_test/iml_buche_test/
anotherNode.py
# ROS2 Python library
import rclpy
from rclpy.node import Node
class MyNode2(Node):
def __init__(self):
super().__init__('my_node_name_another')
self.create_timer(0.2, self.timer_callback)
def timer_callback(self):
self.get_logger().info("Coucou -- Hello ROS2 -- this is IML ")
def main(args=None):
rclpy.init(args=args)
node = MyNode2()
rclpy.spin(node)
rclpy.shutdown()
if __name__ == '__main__':
main()
Do not forget to add another entry point in
setup.py
#...
entry_points={
'console_scripts': [
'test_python_node = iml_buche_test.start:main',
'test_python_another_node = iml_buche_test.anotherNode:main'
],
...
Compile :
$ colcon build
In one terminal :
$ . install/setup.bash
$ ros2 run iml_buche_test test_python_node
In another terminal :
$ . install/setup.bash
$ ros2 run iml_buche_test test_python_another_node
Publisher/Receiver
Create a new package in the workspace
$ cd ./ros2_ws/src
$ ros2 pkg create --build-type ament_python iml_buche_test_2
publisher.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class MinimalPublisher(Node):
def __init__(self):
super().__init__('minimal_publisher')
self.publisher_ = self.create_publisher(String, 'iml_topic', 10)
timer_period = 0.5 # seconds
self.timer = self.create_timer(timer_period, self.timer_callback)
self.i = 0
def timer_callback(self):
msg = String()
msg.data = 'Hello World: %d' % self.i
self.publisher_.publish(msg)
self.get_logger().info('Publishing: "%s"' % msg.data)
self.i += 1
def main(args=None):
rclpy.init(args=args)
minimal_publisher = MinimalPublisher()
rclpy.spin(minimal_publisher)
rclpy.shutdown()
if __name__ == '__main__':
main()
receiver.py
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class MinimalSubscriber(Node):
def __init__(self):
super().__init__('minimal_subscriber')
self.subscription = self.create_subscription(
String,
'iml_topic',
self.listener_callback,
10)
self.subscription # prevent unused variable warning
def listener_callback(self, msg):
self.get_logger().info('I heard: "%s"' % msg.data)
def main(args=None):
rclpy.init(args=args)
minimal_subscriber = MinimalSubscriber()
rclpy.spin(minimal_subscriber)
rclpy.shutdown()
if __name__ == '__main__':
main()
While running, you can display the graph
$ rqt_graph