These are sample solutions for the Python scripts from Coding Exercises #1 (Turtlebot3 Spinning in Circles) and #2 (Turtlebot3 Stopping in Front of a Wall) from Lab A.
spin_in_circles.py
#!/usr/bin/env python3
import rospy
# msgs needed for /cmd_vel
from geometry_msgs.msg import Twist, Vector3
class SpinCircles(object):
""" This node publishes ROS messages containing the 3D coordinates of a single point """
def __init__(self):
# initialize the ROS node
rospy.init_node('spin_circles')
# setup publisher to the cmd_vel ROS topic
self.robot_movement_pub = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
def run(self):
# setup the Twist message we want to send
my_twist = Twist(
linear=Vector3(0.1, 0, 0),
angular=Vector3(0, 0, 0.25)
)
# allow the publisher enough time to set up before publishing the first msg
rospy.sleep(1)
# publish the message
self.robot_movement_pub.publish(my_twist)
if __name__ == '__main__':
# instantiate the ROS node and run it
node = SpinCircles()
node.run()
stop_at_wall.py
#!/usr/bin/env python3
# TOPICS:
# cmd_vel: publish to, used for setting robot velocity
# scan : subscribing, where the wall is
import rospy
# msg needed for /scan.
from sensor_msgs.msg import LaserScan
# msgs needed for /cmd_vel.
from geometry_msgs.msg import Twist
from geometry_msgs.msg import Vector3
# How close we will get to wall.
distance = 0.4
class StopAtWall(object):
""" This node walks the robot to wall and stops """
def __init__(self):
# Start rospy node.
rospy.init_node("walk_to_wall")
# Declare our node as a subscriber to the scan topic and
# set self.process_scan as the function to be used for callback.
rospy.Subscriber("/scan", LaserScan, self.process_scan)
# Get a publisher to the cmd_vel topic.
self.twist_pub = rospy.Publisher("/cmd_vel", Twist, queue_size=10)
# Create a default twist msg (all values 0).
lin = Vector3()
ang = Vector3()
self.twist = Twist(linear=lin,angular=ang)
def process_scan(self, data):
# Determine closeness to wall by looking at scan data from in front of
# the robot, set linear velocity based on that information, and
# publish to cmd_vel.
# This code assumes that you're using an LDS-01 LiDAR model where the
# first entry in data.ranges corresponds with what's directly in
# front of the robot.
if (data.ranges[0] == 0.0 or data.ranges[0] >= distance):
# Go forward if not close enough to wall.
self.twist.linear.x = 0.1
else:
# Close enough to wall, stop.
self.twist.linear.x = 0
# Publish msg to cmd_vel.
self.twist_pub.publish(self.twist)
def run(self):
# Keep the program alive.
rospy.spin()
if __name__ == '__main__':
# Declare a node and run it.
node = StopAtWall()
node.run()