ROS2 - gregory-j-r/Anki-Vector-ROS2 GitHub Wiki
These are instructions for installing Ros2 Foxy on ubuntu 20.04 systems, further details can be found at https://docs.ros.org/en/foxy/Installation/Ubuntu-Install-Debians.html
Run the following commands in terminal:
sudo apt update && sudo apt install curl gnupg2 lsb-release
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null
sudo apt update
sudo apt install ros-foxy-desktop
source /opt/ros/foxy/setup.bash
sudo apt install -y python3-argcomplete
If you want to avoid sourcing every time run:
echo "source /opt/ros/foxy/setup.bash" >> ~/.bashrc
Next you’ll want to install colcon:
sudo apt install python3-colcon-common-extensions
Now you’re ready to start making a workspace, with packages residing in the src folder:
mkdir -p ~/ros2_ws/src
And to make a package, first cd into the src directory:
cd ~/ros2_ws/src
Then run the following commands:
For Cpp and/or Python Package:
ros2 pkg create --build-type ament_cmake <package_name>
For Python only package:
ros2 pkg create --build-type ament_python <package_name>
NOTE: the ament_cmake option is far more powerful as it lets you use cpp and python nodes in the same package, and it lets you create custom message types, which I will cover shortly.
Now it’s time to populate the package you created.
If you used ament_cmake:
cd ~/ros2_ws/src/<pkg_name>
mkdir <pkg_name>
touch <pkg_name>/__init__.py
NOTE: you will put all python scripts in ~/ros2_ws/src/<pkg_name>/<pkg_name>
In the ~/ros2_ws/src/<pkg_name> directory, locate CMakeLists.txt and edit it to contain:
find_package(ament_cmake_python REQUIRED)
find_package(rclpy REQUIRED)
find_package(std_msgs REQUIRED)
ament_python_install_package(${PROJECT_NAME})
install(PROGRAMS
<pkg_name>/script1.py
<pkg_name>/script2.py
DESTINATION lib/${PROJECT_NAME}
)
Where script1.py, script2.py are your actual scripts, and if you have a different quantity simply follow the same format.
NOTE: Make sure to put all that before ament_package()
NOTE: If using ament_cmake then you need to include:
#!/usr/bin/env python3
At the start of every Python script.
If you used ament_python:
Save python scripts in the directory:
~/ros2_ws/src/package_name/package_name/
In the ~/ros2_ws/src/package_name directory locate and edit the package.xml file And below the line add in:
<exec_depend>your_python_import_here</exec_depend>
In the ~/ros2_ws/src/package_name directory locate and edit the setup.py script so that the entry points section looks like
entry_points={
'console_scripts': [
'node1 = package_name.node1_script_name:main',
'node2 = package_name.node2_script_name:main',
],
},
NOTE: node1,node2,node3,...,nodeN, are just names , can be anything unique
Finally it’s time to build and run your package:
If used ament_cmake:
cd ~/ros2_ws/
colcon build --packages-select <package_name>
cd ~/ros2_ws/
. install/setup.bash
ros2 run <package_name> <script_name.py>
If used ament_python:
cd ~/ros2_ws/
colcon build --packages-select <package_name>
cd ~/ros2_ws/
. install/setup.bash
ros2 run <package_name> <node_name>
A message is a set of data that is passed from one node to another. Standard message types include Strings, Integers, arrays, etc.. (standard data types, and can vary in size, ie: 8bit, 16bit etc.).
Ros2, much like Ros, breaks a system down into any number of modular nodes. Nodes communicate with each other via message sending. It is important that these messages go to the correct location, and are seen by the correct recipient. The main ways Ros2 solves this problem are Topics, Services, and Actions.
Any node can publish or subscribe to any number of topics. When one node publishes to a topic, the message they publish is then visible to any node that is subscribing to the same topic. This is a good way to maintain a constant stream of information from one place to another. An example of where you would use a topic is when sending a video feed, where you need a constant stream of data.
Services provide another mode of communication between nodes. Unlike the topics constant stream of data, the service only provides data when it receives a request. A message is sent from one node to another, the receiver does something, and then sends back a single message to the sender. An example of where you would use a service is when you have a connection to establish, a request is sent, the connection is made, and a confirmation is returned.
Actions are similar to services, but are intended for longer running tasks. Actions receive requests, and return both feedback and a result. Unlike a service, an action is cancelable mid request, and provides feedback during the process. An example of where you would use an action could be the rotation of a robot, you may send a “goal” angle, the current angle will be relayed back to the sender while the motion is taking place, and the final achieved angle will be sent upon completion (and as an added bonus you can cancel the rotation at any given point).
Ros2 offers many types of messages publishable to topics (integers, strings, image_arrays, etc…) but when making a request via a service or an action there are few options. This is because a service data type defines both a request message and a response message, and the combinations of these are far too large to cover in just the base install. To deal with this issue Ros2 allows you to define your own message, service, or action data types. Here is how to make custom message and service types:
Step 1: Create new package, must be cmake type: (ROS2 does not support custom message, service, or action creation in purely python environments)
ros2 pkg create --build-type ament_cmake <pkg_name>
Step 2: Make and populate msg and/or srv directories
cd ~/ros2_ws/src/<pkg_name>
mkdir srv
mkdir msg
Then in msg directory make file called <msg_name>.msg And in srv directory make file called <srv_name>.srv
Open <msg_name>.msg populate with:
(for example: int64 num)
Open <srv_name>.msg populate with:
<data_type1> <variable1_name>
<data_type2> <variable2_name>
---
<data_type> <variable_name>
Where variables above the horizontal line are inputs and below are outputs. (Can have as many as you like of each)
Step 3: Edit Cmake.txt and package.xml
Add the following lines to cmake.txt:
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
"msg/Num.msg"
"srv/AddThreeInts.srv"
)
Note: be sure to add above ament_package()
Add the following lines to package.xml:
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>geometry_msgs</depend>
<build_depend>rosidl_default_generators</build_depend>
<member_of_group>rosidl_interface_packages</member_of_group>
Note: add at deepest indentation (ie: right after <test_depend> section fine at same indent as that)
Step 4: Build
cd ~/ros2_ws
colcon build --packages-select <pkg_name>
. install/setup.bash
Step 5: Check that everything setup correct
ros2 interface show <pkg_name>/msg/<msg_name>
Should display: <data_type>
ros2 interface show <pkg_name>/srv/<srv_name>
Should display input and output data types