This is the second assignemnt of the Research Track 1. ROS(Robot Operating System) has been used to control the robot in the environment.
The simulator requires ROS (Robot Operating System), which is a set of software libraries and tools that help you build robot applications. The simulator perfectly runs on the Noetic Release of ROS, I haven't tried the ROS 2 release yet, so let me know if it does actually work. Once you have install the ROS, you have to create your own workspace where you can build packages. Thereafter you have to copy the code into src folder of your workspace
Firstly, you need to run the master node in your terminal to run the ROS in your PC.
roscore &
Secondly, you need to run the given command in the root of your workspace to build the workspace.
catkin_make
Then you have to run rospack profile in order to refresh your packages.
rospack profile
Now you have to run the folloeing nodes in the root of your workspace
rosrun stage_ros stageros $(rospack find second_assignment)/world/my_world.world
rosrun second_assignment robotController_node
Seccondly, you need to run the Server node which handles service to manage request from the user and give the responce to the user node.
rosrun second_assignment server_node
Finally, you need to run the User node which takes input from the user and send the request to the server node and waiting for the response from the server node.
rosrun second_assignment user_node
The simulation here shows the movemnet of the robot in the environment.
Here I will explain each node code and tasks, to have a deeper description of the code, check the comments inside of it.
The stageros node wraps the Stage 2-D multi-robot simulator, via libstage. Stage simulates a world as defined in a .world file. This file tells stage everything about the world, from obstacles (usually represented via a bitmap to be used as a kind of background), to robots and other objects. The nodes has the following aspects:
- Subscriptions
- The node subscribes to the
cmd_vel (geometry_msgs/Twist)
topic, to manage the velocity of the robot.
- The node subscribes to the
- Publishing
odom (nav_msgs/Odometry)
: odometry data of the model.base_scan (sensor_msgs/LaserScan)
: scans from the laser model. We will use this one.base_pose_ground_truth (nav_msgs/Odometry)
: the ground truth pose. We will use this one.image (sensor_msgs/Image)
: visual camera image.depth (sensor_msgs/Image)
: depth camera image.camera_info (sensor_msgs/CameraInfo)
: camera calibration info.
The robotContrioller node has two main tasks, the first is to move the robot inside the enviroment and second changes the velocity of the robot. These tasks are completed with the callback function and the main of the node. The main()
initialise the node with the init() function and subscribes to different topics.
- Subscriptions
base_scan (sensor_msgs/Laser_scan)
which provides data about the laser that scans the surroundings of the robot.robotSpeed (second_assignment/robotSpeed)
which gives the speed to add to the base velocity.
- Publishing
-
cmd_vel geometry_msgs/Twist
which is the topic to change the linear and angular velocity's values of the robot.In thisi case, the red block represents the operations of the robotController node. It has subscribed the
base_scan
topic of the stageros node androbotSpeed
message and publishing the velocity on thecmd_vel geometry_msgs/Twist
which, in result, oving the robot in the evironment correctly. The controller logic flowchart is shown below.
-
This is the server node which takes the user request and send the response according to the user node's demand.
- 'a' to accelerate.
- 'd' to decelerate.
- 'r' to reset the position of the robot inside the circuit.
bool ServerCallback(second_assignment::speedRequest::Request &req, second_assignment::speedRequest::Response &res){
// If the input is 'a' or 'A' The speed of the robot wil increace.
if(req.in == 'a' || req.in == 'A'){
pos += 0.5;
}
// If the input is 's', The speed of the robot will decreace.
if(req.in == 'd' || req.in == 'D'){
pos -= 0.5;
}
// If the input is 'r', the position of robot will reset
// By calling reset serrvice
if(req.in == 'r' || req.in == 'R'){
ros::service::call("/reset_positions", res_server);
}
This is the user interface node which talks with the user to input the command and give the response to the user node. For further details, please see the comments inside the code
int main (int argc, char **argv)
{
// Initialize the node, setup the NodeHandle
// for handling the communication with the
// ROS //system.
ros::init(argc, argv, "UserInterface");
ros::NodeHandle nh;
char a;
// Defining the publishing of the message Accval.
pub = nh.advertise<second_assignment::robotSpeed>("/robotSpeed", 10);
// Creating the client with his attributes.
client1 = nh.serviceClient<second_assignment::speedRequest>("/speedRequest");
// Making the function spin.
while(1){
// Reading the input from user
std::cout << "PRESS D, IF YOU WANT TO DECREASE THE SPEED OF THE ROBOT\n";
std::cout << "PRESS A, IF YOU WANT TO INCREASE THE SPEED OF THE ROBOT\n";
std::cout << "If you want to reset, press 'r'!\n";
std::cin >> a;
// Creating a variable to send a request
// to the server "speedRequest".
second_assignment::speedRequest a_srv;
// Sending a char as request.
a_srv.request.in = a;
// Waiting for the server to give a response.
client1.waitForExistence();
client1.call(a_srv);
// Creating a message to send the response to
// robotController.cpp
second_assignment::robotSpeed n;
n.speed = a_srv.response.out;
pub.publish(n);
ros::spinOnce();
}
return 0;
}
The red block in the rqt graph show the operation of the user interface. The UserInterface node is publishing the instructions to the message robotSpeed by using server that server is giving the incremented value to the to the basic speed or velocity variable of the robot which is resonsible for the accelaration of the robot.
To sum it all up, I've controlled the robot in the given environment by using ROS functionalities and impplemented the concepts of nodes, topics, custom messages and custom services by particularly fousing on the assignemnt requirements. The whole conficuration of the system communication is shown in the rqt graph. To see the rqt graph in your system, you must need to run the node given below.
rosrun rqt_graph rqt_graph
However, this is the first assignmnet that has been done by me on the ROS framework and I'm well aware of the ROS functionalities. Still, lots of improvements can be done.
- Firstly, The movement of the robot in the environment can be improved by developing more effective logic because the robot is facing a bit trouble while turning and search a lot.
- Secondly, The movemnet of the robot can be improved by further subdivision of the laser ranges like frontleft and front right. I tried to do that;however, in a few cases it started moving in the opposite direction while turning. Overall, The movemnet can be improved by implementing the logic in more effective way.