Creating a node which contains both a subscriber and publisher with Python Class
I am creating a node to solve the following quiz: In this Quiz, you will create a code to make the robot avoid the wall that is in front of him. To help you achieve this, let's divide the project down into smaller units:
In this Quiz, you will create a code to make the robot avoid the wall that is in front of him. To help you achieve this, let's divide the project down into smaller units:
- Create a Publisher that writes into the /cmd_vel topic in order to move the robot.
- Create a Subscriber that reads from the /kobuki/laser/scan topic. This is the topic where the laser publishes its data.
- Depending on the readings you receive from the laser's topic, you'll have to change the data you're sending to the /cmd_vel topic, in order to avoid the wall. This means, use the values of the laser to decide.
My solution which doesn't work is shown as below:
#! /usr/bin/env python
import rospy
from sensor_msgs.msg import LaserScan
from geometry_msgs.msg import Twist
class LaserCmdNode(object):
def __init__(self, topic_name='/kobuki/laser/scan'):
self._topic_name = topic_name
self._laser_scan_sub = rospy.Subscriber(
'/kobuki/laser/scan', LaserScan, self.topic_callback)
self._laserscan_object = LaserScan()
self._cmd_vel_pub = rospy.Publisher('/cmd_vel', Twist, queue_size=1)
self._twist_object = Twist()
def topic_callback(self, msg):
self._laserscan_object = msg
print self._laserscan_object.ranges[360]
# self.get_laserscan_to_cmd()
# return self._laserscan_object
def get_laserscan_to_cmd(self):
# return self._laserscan_object
if self._laserscan_object.ranges[360] > 1:
self._twist_object.linear.x = 0.1
self._twist_object.angular.z = 0
if self._laserscan_object.ranges[360] < 1:
self._twist_object.linear.x = 0
self._twist_object.angular.z = 0.5
if self._laserscan_object.ranges[719] < 1:
self._twist_objectd.linear.x = 0
self._twist_object.angular.z = -0.5
if self._laserscan_object.ranges[0] < 1:
self._twist_object.linear.x = 0
self._twist_object.angular.z = 0.5
else:
pass
# pub.publish(self._twist_object)
self._cmd_vel_pub.publish(self._twist_object)
if __name__ == "__main__":
rospy.init_node('laserscan_cmd_node')
LaserCmdNode_class_object = LaserCmdNode()
rate = rospy.Rate(1)
ctrl_c = False
def shutdownhook():
global ctrl_c
print "shutdown time! Steven is a great guy and he never gives up. He is gonna earn his PhD soon."
rospy.on_shutdown(shutdownhook)
while not ctrl_c:
LaserCmdNode_class_object.get_laserscan_to_cmd()
rate.sleep
After I made the following change the code works as expected: I made the following two change in my code and it starts working. First, I added self.get_laserscan_to_cmd() in my def topic_callback(self, msg): Secondly, I commented out this line : LaserCmdNode_class_object.get_laserscan_to_cmd() in my if name == "main": With your expertise, do you know why it works this time? Do I have to call my get_laserscan_to_cmd() in my topic_callback function? Why can't I call it in my if name == "main": part of code?Thanks a lot?
The following is the working code after my changes:
! /usr/bin/env python
import rospy
from sensor_msgs.msg import LaserScan
from geometry_msgs.msg import Twist
class LaserCmdNode(object):
def __init__(self, topic_name='/kobuki/laser/scan'):
self._topic_name = topic_name
self._laser_scan_sub = rospy.Subscriber(
'/kobuki ...