Second assignment of the Research Track 1 course of the Master's degree in Robotics Engineering at the University of Genoa.
https://alessandrotrovatello.github.io/RT1_assignment2/
- Assignment description
- ROS Architecture
- How to download the repository
- How to run the code
- Possible improvements
The main task of this assignment is to create a ROS package which must include the following three nodes:
- A node that implements an action client, allowing the user to set a target (x, y) or to cancel it. Trying to use the feedback/status of the action server to know when the target has been reached. The node also publishes the robot position and velocity as a custom message (x,y, vel_x, vel_z), by relying on the values published on the topic /odom;
- A service node that, when called, returns the coordinates of the last target sent by the user;
- Another service node that subscribes to the robot’s position and velocity (using the custom message) and implements a server to retrieve the distance of the robot from the target and the robot’s average speed.
Another task is to create a launch file to start the entire simulation, in which a parameter must be used to select the size of the averaging window.
The starting point of the assignment is reachable in the starting_point branch. Nodes already implemented are go_to_point_service.py, wall_follow_service.py and bug_as.py that manages the robot's algorithm in reaching the goal, such as system messages and obstacle avoidance management.
The ROS architecture consists of a few nodes that communicate with each other via msgs published in topics. The library that allows us to set and send the target (or goal) is actionlib, this ROS library is used to handling asynchronous tasks. It facilitates communication between a client and a server node, supporting the execution of long-duration tasks with asynchronous feedback. Key features include asynchronous communication, feedback during task execution, result reporting, goal specification, and support for retries in case of failure. It enhances the robustness and efficiency of managing complex actions in robotic systems.
To give a better idea of how the architecture is composed, this below is a graph of the ROS architecture:
Where we can see how the nodes, the msg and srv communicate with each other, in a better and clearly way.
The nodes developed are an action client and two service node to get information about last target coordinates and the distance between the robot and target and the average speed of the robot:
- action_client is the node that allows us to get the goal coordinates from the user to be sent to the server throught the
/reaching_goal
topic; the node allows us to cancel the goal while the robot is reaching the goal. Additionally, the node publish the information about robot position and velocity in a/robot_pos_vel
topic as a custom message. The following flowchart explains how the action client is structured:
There is a little control on the user input to get only coordinates in range to [-9,9] due to the size of the environment (10x10 grid), furthermore there is a goal threshold to prevent the robot from not reaching the desired position in case that position is occupied by an obstacle.
- last_target_service is a service node that allows us to get the last goal coordinates from the
/reaching_goal/goal
topic. This info is can be retrieved calling the service as below:
rosservice call /last_target
-
avg_service is a service node that allows us to get the goal coordinates from the ROS param, defined in the assignment1.launch, by using rospy.get_param("param_name"), the robot position and the robot velocity are get from the
/robot_pos_vel
topic, created on action_client node. This service calculate the distance between robot and target using their coordinates in the Euclidean formula$c=\sqrt{a^2+b^2}$ , where 'c' is the distance between robot and target (hypotenuse) while 'a' and 'b' are the x and y components difference (cathetuses). In addition, the service calculate the average linear velocity along robot x-axis and the average angular velocity around robot z-axis, using a parameter to set the size of the averaging window, this value as default is 10, then the avg is obtained by the arithmetic mean$m=\frac{a_1 + a_2 + \ldots + a_n}{n}$ where 'n' is the window size param. The service can be called writing:
rosservice call /avg_dist_vel
The assignment is developed in Ubuntu 20.04 LTS using ROS Noetic, while the simulation environmnet used is Gazebo (not to be downloaded).
The code must be cloned within your ROS workspace, if you already have a ROS workspace skip the next steps until the xterm installation.
To setup your own ROS workspace, the first step is to create a new directory:
mkdir directory_name
And move in it:
cd directory_name
Now you are inside the directory_name folder and you need to create another directory with the name 'src':
mkdir src
At this point you are ready to set up your ROS workspace with the following command:
catkin_make
To help you understand the steps I attach a photo of what your terminal should look like:
Then, press enter and your ROS workspace will be compiled, two directory are will be created inside your workspace.
The last step is to insert the path of your ROS workspace inside the .bashrc
file to make sure you are running your ROS workspace every time you open the terminal. So, go back with the following command:
cd ..
And open your .bashrc
file:
gedit .bashrc
Scroll the page until the end and insert your ROS workspace path, if you have followed the steps it should be:
source ~/directory_name/devel/setup.bash
In this way (note that there should be a command line to start ROS Noetic source /opt/ros/noetic/setup.bash
):
Save the file and restart the terminal, you're Done!
To run the code is necessary to install xterm
; a kind terminal for a clearer overview:
sudo apt-get -y install xterm
To download this repository, move to the src
folder inside your ROS workspace. Now you can clone this repository by using GIT in this way:
git clone https://github.com/alessandrotrovatello/RT1_assignment2
After that, return in your ROS workspace, using cd ..
command, and re-compile your workspace using catkin_make
.
You are ready tu run the code!
The time to run the code has come, so, all you have to do is run the .launch file and the simulation will open up:
roslaunch assignment_2_2023 assignment1.launch
Will open: three white xterm terminals, RViz (ROS Visualisation) to display the robot data and the Gazebo simulation environment. Once everything is open, it's time to test the code!
Now you can set the goal coordinates inside the action_client.py
xterm terminal. For example: x = 3, y = 3.5 and the robot will start to reaching the goal.
Once the goal has been reached, it will be print the robot's position and orientation. While the robot is moving, you can call the services implemented by opening a new terminal and typing:
To retrieve the last goal coordinates:
rosservice call /last_target
And you can see the result inside the last_target_service.py
xterm terminal:
To retrieve the distance between the robot and the target, the average of linear velocity along robot x-axis and the average of angular velocity along robot z-axis:
rosservice call /avg_dist_vel
And you can see the result inside the avg_service.py
xterm terminal:
It will certainly be possible to cancel the set goal while the robot is in motion and set a new goal coordinates.
The simulation has a few problems, such as the robot could get stuck near an obstacle, to avoid this problem one could implement the reverse gear so that the robot could be unstack. Also, one could increase the robot's speed while being careful as the robot is very light, but for this one could modify the robot's physics. The most significant improvement I would make is the management of the choice of whether to go around an obstacle from the right or the left depending on the geometry of the obstacle, sometimes this problem could lengthen the time to reach the goal by a lot; the robot is equipped with a scan that can see the obstacles, you could make it make decisions based on its surroundings.