Welcome to your first hands-on ROS2 mini-project! Today you will create a custom ROS2 package from scratch, write a controller node in Python, and drive a simulated turtle to a target GPS coordinate.
Timeframe: 1 Hour
Tooling: Working with the Wisconsin Robotics workspace and Dev containers / ROS2 Humble / Python (rclpy)
AI Usage: Strongly encouraged! Ask strategic questions about ROS2 architecture, rclpy callbacks, and control logic.
Clone this git repository in your WroverSoftware_Docker/workspace directory, and then launch the docker container for main.
sudo apt update && sudo apt install -y ros-humble-turtlesimYour workspace contains a pre-built package:
mock_gps: Publishes simulated turtle location data to/turtle/gps.
You will create a new package called turtle_control alongside it.
Navigate to your workspace src directory and generate a new Python package with pre-configured dependencies:
cd /workspace/ROS2_training_project/src
ros2 pkg create --build-type ament_python turtle_control --dependencies rclpy geometry_msgsInside src/turtle_control/turtle_control/, create a new Python file named turtle_controller.py:
Open src/turtle_control/setup.py and register your node under entry_points. This makes your Python script executable via ros2 run:
entry_points={
'console_scripts': [
'turtle_controller = turtle_control.turtle_controller:main',
],
},- In
turtle_controller.py, set up a basicrclpyNode class. - Create a subscriber listening to
/turtle/gpsusing message typegeometry_msgs/msg/Point. - In the callback function, print the current
x(lat) andy(lon) coordinates to the console usingself.get_logger().info(...).
- Define a target coordinate inside your node (e.g.,
target_x = 10,target_y = 10). This will be provided during the meeting (probably will be 10,10). - Create a publisher on topic
/turtle1/cmd_velusing message typegeometry_msgs/msg/Twist. - In your GPS callback, compute:
- Distance error:
distance = sqrt((target_x - current_x)^2 + (target_y - current_y)^2)- This is the Euclidean distance formula - Desired heading:
angle = atan2(target_y - current_y, target_x - current_x)- This is the formula to compute angle between your current heading and the desired heading.
- Distance error:
- Publish linear velocity (
linear.x) and angular velocity (angular.z) commands to steer and move the turtle toward the target coordinate. You must publish to /turtle1/cmd_vel - figure out which topic to publish to by running:
ros2 topic listNote: This will only work for
If you finish Steps 1–3 early:
- Make the target coordinate dynamic by subscribing to
/target_gps(geometry_msgs/msg/Point). - When distance to target is less than
0.2units:- Set linear velocity to
0.0. - Print
"Target Reached!"to the logger. - Perform a 360-degree spin in place.
- Set linear velocity to
- Now write a launch file for both mock_gps and for turtle_control (see step 5)
To launch your ROS 2 node along with any necessary configurations, create a dedicated launch file.
- Create a launch/ directory inside your package root if it doesn't already exist:
mkdir -p /workspace/ROS2_training_project/src/your_package_name/launchYou only need to create one launch file and it can launch all your nodes 2. Create a python file named your_file_name.py
import os
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='your_package_name',
executable='', # Name specified in setup.py console_scripts
name='target_navigator_node',
output='screen',
parameters=[
# Add parameters here if needed (e.g., target tolerance)
{'distance_threshold': 0.2}
],
remappings=[
# Optional topic remappings
('/target_gps', '/target_gps')
]
)
])To add more Nodes simply add more node objects like: Node() 3. Update setup.py (the data_files list) to ensure the launch file installs properly
# Include all launch files from the launch directory:
(os.path.join('share', package_name, 'launch'), glob(os.path.join('launch', '*launch.[pxy][yma]'))),- Build the package and run the launch file
cd /workspace/
colcon build --packages-select your_package_name
source install/setup.bash
ros2 launch your_package_name your_file_name.pyEvery time you modify your code:
-
Build the workspace:
cd /workspace/ROS2_training_project/ colcon build --packages-select turtle_control --symlink-install -
Source the workspace (In EVERY new terminal):
source install/setup.bash -
Execution Order:
- Terminal 1: Launch turtlesim (
ros2 run turtlesim turtlesim_node) - Terminal 2: Launch the mock GPS node (
ros2 run mock_gps mock_gps_node) - Terminal 3: Run your new controller (
ros2 run turtle_control turtle_controller)
- Terminal 1: Launch turtlesim (
Avoid asking AI to write the whole project at once. Break it down:
- "Show me a minimal boilerplate for a ROS2 Python node using rclpy."
- "How do I create a subscriber for geometry_msgs/msg/Point in rclpy?"
- "How do I compute proportional angular steering towards a 2D point given current position?"
- Create a branch:
git checkout -b feature/yourname-turtle-control - Commit incrementally:
git commit -m "feat: added gps subscriber" - Push when done to your feature branch.