ROS

ROS1 (Deprecated)

This is deprecated, however I first learned this while following Madhur Behl’s F1TENTH course.

Why the upgrade to ROS2?

To understand why, check out https://design.ros2.org/articles/why_ros2.html. But the spiel is that everything with ROS1 was developed in-house: discovery, message definition, serialization, and transport. With ROS2, we now have things such as DDS (which are developed by 3rd parties.)

The main worry was that ROS1 was not very secure. ROS2 is built using off-the-shelf open source libraries.

Services

Service calls are bidirectional.

Ros launch files exist to lunch a bunch of nodes, so you don’t have to manually launch it every time. Server

#!/usr/bin/env python
import roslib; roslib.load_manifest('beginner_tutorials')
 
from beginner_tutorials.srv import *
import rospy
 
def handle_add_two_ints(req):
    print "Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b))
    return AddTwoIntsResponse(req.a + req.b)
 
def add_two_ints_server():
    rospy.init_node('add_two_ints_server')
    s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
    print "Ready to add two ints."
    rospy.spin()
 
if __name__ == "__main__":
    add_two_ints_server()

Client

#!/usr/bin/env python
import roslib; roslib.load_manifest('beginner_tutorials')
 
import sys
 
import rospy
from beginner_tutorials.srv import *
 
def add_two_ints_client(x, y):
    rospy.wait_for_service('add_two_ints')
    try:
        add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
        resp1 = add_two_ints(x, y)
        return resp1.sum
    except rospy.ServiceException, e:
        print "Service call failed: %s"%e
 
def usage():
    return "%s [x y]"%sys.argv[0]
 
if __name__ == "__main__":
    if len(sys.argv) == 3:
        x = int(sys.argv[1])
        y = int(sys.argv[2])
    else:
        print usage()
        sys.exit(1)
    print "Requesting %s+%s"%(x, y)
    print "%s + %s = %s"%(x, y, add_two_ints_client(x, y))
Rospy

Names most be unique in ROS. use queue_size=1 if you always want the freshest data, queue_size=0 actually means infinite queue size, which is really bad.

Publisher

import rospy
from std_msgs.msg import String
 
def talker():
	pub = rospy.Publisher('chatter', String, queue_size=10) # 'chatter' is the topic name
	rospy.init_node('talker', anonymous=True)
	rate = rospy.Rate(10) # 10 Hz
	while not rospy.is_shutdown():
		hello_str = "hello world %s" % rospy.get_time()
		ropspy.loginfo(hello_str)
		pub.publish(hello_str)
		rate.sleep() # To ensure that we maintain 10hz
 
if __name__ == '__main__':
	try:
		talker()
	except rospy.ROSInterruptException:
		pass

Subscriber

import rospy
from std_msgs.msg import String
 
def callback(data):
	ropspy.loginfo(rospy.get_caller_id())
 
def listener():
	rospy.init_node('listener', anonymous=True)
	rospy.Subscriber('chatter', String, callback)
	rospy.spin() # Keeps Python from exiting until this node is stopped
 
if __name__ == '__main__':
	listener()
Catkin

Catkin is the ROS build system

  • The set of tools that ROS uses to generate executable programs, libraries and interfaces

catkin = CMake + X

Two mandatory files:

  • package.xml
  • CMAKEList.txt
mkdir ~/catkin_ws/src
cd ~/catkin_ws/src
catkin_init_workspace
 
cd ~/catkin_ws
catkin_make # Build the workspace and all the packages within it, ALWAYS do it in ~/
source ./devel/setup.sh
 
catkin clean # Clean the entire build and devel space
 
# Afterwards, for ros, super useful commands
rospack find roscpp # get the directory
rospack depends turtlesim # print the dependencies
 
roscd turtlesim/
rosls turtlesim/

Ros code is grouped at two different levels:

  • Packages
  • Stacks
    • Stack = collection of packages (ex: Perception Stack)
  • Distribution = Collection of stacks
Give permissions
cd ~/catkin_ws
find . -name “*.py” -exec chmod +x {} \; # This DOESNT WORK
catkin_make
source ~/catkin_ws/devel/setup.bash
Basic Commands
roscore # Start ROS and create the Master
 
# rosrun package_name node_name
rosrun turtlesim turtlesim_node
****
rosnode list
rosnode info /turtlesim # Learn more about a particular node
 
rostopic list -v # List of topics
rostopic info /turtle1/pose 
rostopic type /turtle1/pose 
 
rosmsg show turtlesim/Pose 
 
rostopic echo /turtle1/pose # show the messages of a particular topic
 
 
 
rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist # Publishing to a topic manually
 
rosservice call /reset
rosservice call /turtle1/teleport_absolute 1 1 0
 
 
rosrun rqt_graph rqt_graph
 
 
rosnode kill /node_name # This is better than Ctrl-C, there might be dead nodes, 
rosnode cleanup