CS 354 Autonomous Robotics

Fall 2020

Introduction

The purpose of this programming assignment is to work through all of the steps of creating a ROS2 application using Python.

The goal of your project will be to create a Python application that is able to navigate a simulated 2D turtle to a designated goal location.

Resources

Skibot

The simulated robot you'll be working with for this project is Skibot. Skibot is very similar to turtlesim, with the key difference that the Skibot turtle has a physics-based motion model. Instead of directly setting the velocity of the turtle using geometry_msgs/msg/Twist messages, you will apply forces using geometry_msgs/msg/Wrench messages.

Your first step for this project is to clone the Skibot repository from Github (https://github.com/JMU-ROBOTICS-VIVA/skibot). Once you have cloned the repository, you will need to place it in your dev_ws/src folder, and build using colcon. Skibot depends on Pygame, so you may need to install Pygame if it isn't already available on your system. Make sure you can interact with the simulator from the command line before starting work on your code.

Part 1 - Setting Up The Repository

Follow the GitHub classroom link to create a repository. For this project your repository will need to contain two separate ROS2 packages. This is necessary because you'll be using a custrom srv type that must be compiled in a separate package. This means your repository layout should be as follows:

your_repo/                       <-- Name doesn't matter
    skibot_nav/                  <-- Your skibot control ROS2 package
    skibot_nav_interfaces/       <-- Your skibot control interfaces package

Therefore, when you clone your repository into your workspace, the overall directory structure will look like this:

dev_ws/
    src/
        your_repo/
            skibot_nav/
            skibot_nav_interfaces/

This organization is fine. It isn't necessary for packages to be directly under the src folder.

Go ahead and setup the skibot_nav package. The steps here will be similar to the ROS Packing lab we completed earlier. The only dependency you need to specify is skibot. The entry point should be skibot_nav_node.

Part 2 - Navigation

Update skibot_nav_node.py so that it moves the skibot in a smooth trajectory to a designated goal location. Ultimately, the goal location will be provided through the mechanism of ROS services, but to get started you can just hard-code a goal location in your Python code. You should be able to test your node by starting the skibot_node node, then running skibot_nav_node.py.

If your code is correct, and your package is configured correctly, you should be able to type:

ros2 run skibot_nav skibot_nav_node

and watch your skibot merrily navigate to the goal.

Part 3 - Navigation as a Service

The next step is to provide a mechanism for communicating goal locations to the skibot_nav_node. We will accomplish this by converting the node you developed above into a ROS2 service provider.

Your modified node must meet the following requirements:

  • The service name must be move_skibot_to_point.
  • You must use the service type SkibotToPoint.srv.
  • If the goal location is reachable by the skibot, then your node must navigate to within .01 meters of the goal, and then return a value of True. Note that navigation is only considered successful if the robot stops at the goal. Sliding over the goal is not sufficient.
  • If the goal location is not reachable, then the your node must return a value of False. Locations are unreachable in the skibot simulation if they have x or y coordinates less than zero or greater than 4.0.

Once your service is running, you should be able to test it by making calls from the terminal:

$ ros2 service call /move_skibot_to_point skibot_nav_interfaces/srv/SkibotToPoint "{goal_x: 3, goal_y: 3}"
waiting for service to become available...
requester: making request: skibot_nav_interfaces.srv.SkibotToPoint_Request(x=3.0, y=3.0)

response:
skibot_nav_interfaces.srv.SkibotToPoint_Response(success=True)

$ ros2 service call /move_skibot_to_point skibot_nav_interfaces/srv/SkibotToPoint "{goal_x: 25, goal_y: 3}"
waiting for service to become available...
requester: making request: skibot_nav_interfaces.srv.SkibotToPoint_Request(x=3.0, y=3.0)

response:
skibot_nav_interfaces.srv.SkibotToPoint_Response(success=False)

Part 4 - Creating a Launch File

Create a launch file named skibot_nav.launch.py that handles starting the skibot node and the navigation service node. I should be able to test your code by typing:

ros2 launch skibot_nav skibot_nav.launch.py

in the terminal, and then making service requests.

Submitting

Your submission will be graded on the basis of functionality, code-quality, documentatation, and adherence to ROS2 packaging standards. Important numerical constants, like gain values, should not be hard-coded into your Python files. They should be configured as ROS2 parameters and set in your launch file.

Submissions will be graded according to the following rubric:

Successfully navigates to goal (possibly hard-coded) 40%
Service requests handled correctly. 20%
Constants provided as ROS2 parameters 10%
Launch file works correctly 10%
Properly organized repository and ROS2 packages 10%
Python code follows ROS2 coding standards 10%