Browse Source

Init commit of avoider node.

pull/1/head
Alan Sanchez 3 years ago
parent
commit
d811b3e25a
1 changed files with 64 additions and 0 deletions
  1. +64
    -0
      src/avoider.py

+ 64
- 0
src/avoider.py View File

@ -0,0 +1,64 @@
#!/usr/bin/env python
# Every python controller needs these lines
import rospy
from numpy import linspace, inf, tanh
from math import sin
# The Twist message is used to send velocities to the robot.
from geometry_msgs.msg import Twist
# We're going to subscribe to a LaserScan message.
from sensor_msgs.msg import LaserScan
class Avoider:
def __init__(self):
# Set up a publisher and a subscriber. We're going to call the subscriber
# "scan", and filter the ranges similar to what we did in example 2.
# For the publisher, we're going to use the topic name /stretch/cmd_vel.
self.pub = rospy.Publisher('/stretch/cmd_vel', Twist, queue_size=1) #/stretch_diff_drive_controller/cmd_vel for gazebo
self.sub = rospy.Subscriber('/scan', LaserScan, self.set_speed)
# We're going to assume that the robot is pointing up the x-axis, so that
# any points with y coordinates further than half of the defined
# width (1 meter) from the axis are not considered.
self.width = 1
self.extent = self.width / 2.0
self.distance = 0.5
# Alocate a Twist to use, and set everything to zero. We're going to do this here, to save some time in
# the callback.
self.twist = Twist()
self.twist.linear.x = 0.0
self.twist.linear.y = 0.0
self.twist.linear.z = 0.0
self.twist.angular.x = 0.0
self.twist.angular.y = 0.0
self.twist.angular.z = 0.0
# Called every time we get a LaserScan message from ROS.
def set_speed(self,msg):
# Figure out the angles of the scan. We're going to do this each time, in case we're subscribing to more than one
# laser, with different numbers of beams.
angles = linspace(msg.angle_min, msg.angle_max, len(msg.ranges))
# Work out the y coordinates of the ranges.
points = [r * sin(theta) if (theta < -2.5 or theta > 2.5) else inf for r,theta in zip(msg.ranges, angles)]
# If we're close to the x axis, keep the range, otherwise use inf, which means "no return".
new_ranges = [r if abs(y) < self.extent else inf for r,y in zip(msg.ranges, points)]
error = min(new_ranges) - self.distance
# Using hyperbolic tanget for speed regulation
self.twist.linear.x = tanh(error) if (error > 0.05 or error < -0.05) else 0
self.pub.publish(self.twist) # Publish the command using the global publisher
if __name__ == '__main__':
rospy.init_node('avoider')
Avoider()
rospy.spin()

Loading…
Cancel
Save