|
| 1 | +#!/usr/bin/env python |
| 2 | +import rospy |
| 3 | +from geometry_msgs.msg import Twist |
| 4 | +#from turtlesim.msg import Pose |
| 5 | +from math import pow,atan2,sqrt |
| 6 | +from nav_msgs.msg import Odometry |
| 7 | +import tf |
| 8 | +import math |
| 9 | +from math import radians, degrees |
| 10 | + |
| 11 | + |
| 12 | +def getYaw(self): |
| 13 | + quaternion = (self.pose.pose.pose.orientation.x, self.pose.pose.pose.orientation.y, self.pose.pose.pose.orientation.z, self.pose.pose.pose.orientation.w) |
| 14 | + euler = tf.transformations.euler_from_quaternion(quaternion) |
| 15 | + yaw = angle2pi(euler[2]) |
| 16 | + return yaw |
| 17 | + |
| 18 | + #Changes to 2pi plane |
| 19 | +def angle2pi(angle): |
| 20 | + if (angle < 0): |
| 21 | + angle = angle + (2*math.pi) |
| 22 | + return angle |
| 23 | + |
| 24 | +class gotoXY(): |
| 25 | + |
| 26 | + def __init__(self): |
| 27 | + #Creating our node,publisher and subscriber |
| 28 | + rospy.init_node('gotoXY_straight') |
| 29 | + self.velocity_publisher = rospy.Publisher('/cmd_vel', Twist, queue_size=10) |
| 30 | + self.pose_subscriber = rospy.Subscriber('/odom', Odometry, self.callback) |
| 31 | + #self.pose = Pose() |
| 32 | + self.pose = Odometry() |
| 33 | + self.rate = rospy.Rate(10) |
| 34 | + |
| 35 | + |
| 36 | + #Callback function implementing the pose value received |
| 37 | + def callback(self, data): |
| 38 | + self.pose = data |
| 39 | + self.pose.pose.pose.position.x = round(self.pose.pose.pose.position.x, 4) |
| 40 | + self.pose.pose.pose.position.y = round(self.pose.pose.pose.position.y, 4) |
| 41 | + yaw = getYaw(self) |
| 42 | + |
| 43 | + def move2goal(self): |
| 44 | + #goal_pose = Pose() |
| 45 | + goal_pose = Odometry() |
| 46 | + #print goal_pose |
| 47 | + goal_pose.pose.pose.position.x = input("Set your x goal: ") |
| 48 | + goal_pose.pose.pose.position.y = input("Set your y goal: ") |
| 49 | + current_x = self.pose.pose.pose.position.x |
| 50 | + current_y = self.pose.pose.pose.position.y |
| 51 | + #orientation = input("Set your final orientation: ") |
| 52 | + distance_tolerance = input("Set your tolerance: ") |
| 53 | + angle_tolerance = input("Set your angle tolerance: ") |
| 54 | + vel_msg = Twist() |
| 55 | + |
| 56 | + yaw = getYaw(self) |
| 57 | + direction = atan2(goal_pose.pose.pose.position.y-self.pose.pose.pose.position.y, goal_pose.pose.pose.position.x-self.pose.pose.pose.position.x) |
| 58 | + direction = angle2pi(direction) |
| 59 | + print "direction:" |
| 60 | + print direction |
| 61 | + |
| 62 | + # sets the direction of turn |
| 63 | + clockwise = False |
| 64 | + if (direction - yaw) <= math.pi: |
| 65 | + if abs(direction - yaw) > 0: |
| 66 | + clockwise = False |
| 67 | + else: |
| 68 | + clockwise = True |
| 69 | + if (direction - yaw) > math.pi: |
| 70 | + if abs(direction - yaw) > 0: |
| 71 | + clockwise = True |
| 72 | + else: |
| 73 | + clockwise = False |
| 74 | + |
| 75 | + #Turns the robot |
| 76 | + while abs(yaw - direction) >= angle_tolerance: |
| 77 | + #angular velocity in the z-axis: |
| 78 | + vel_msg.angular.x = 0 |
| 79 | + vel_msg.angular.y = 0 |
| 80 | + v_z = 4 * (direction - yaw) |
| 81 | + |
| 82 | + if abs(v_z) > 1: |
| 83 | + v_z = 1 |
| 84 | + if clockwise == True: |
| 85 | + v_z = -abs(v_z) |
| 86 | + else: |
| 87 | + v_z = abs(v_z) |
| 88 | + |
| 89 | + vel_msg.angular.z = v_z |
| 90 | + print "Yaw:" |
| 91 | + print yaw |
| 92 | + yaw = getYaw(self) |
| 93 | + |
| 94 | + self.velocity_publisher.publish(vel_msg) |
| 95 | + self.rate.sleep() |
| 96 | + print yaw |
| 97 | + vel_msg.angular.z = 0 |
| 98 | + self.velocity_publisher.publish(vel_msg) |
| 99 | + self.rate.sleep() |
| 100 | + |
| 101 | + target_distance = math.sqrt((goal_pose.pose.pose.position.x-self.pose.pose.pose.position.x)**2 + (goal_pose.pose.pose.position.y-self.pose.pose.pose.position.y)**2) |
| 102 | + current_distance = 0 |
| 103 | + |
| 104 | + while (target_distance - current_distance >= distance_tolerance): |
| 105 | + |
| 106 | + #Proportional Controller |
| 107 | + #linear velocity in the x-axis: |
| 108 | + |
| 109 | + v_x = 1.5 * sqrt(pow((goal_pose.pose.pose.position.x - self.pose.pose.pose.position.x), 2) + pow((goal_pose.pose.pose.position.y - self.pose.pose.pose.position.y), 2)) |
| 110 | + if(v_x > 0.5): |
| 111 | + v_x = 0.5 |
| 112 | + vel_msg.linear.x = v_x |
| 113 | + vel_msg.linear.y = 0 |
| 114 | + vel_msg.linear.z = 0 |
| 115 | + print "target_distance:" |
| 116 | + print target_distance |
| 117 | + print "current_distance:" |
| 118 | + print current_distance |
| 119 | + #target_distance = math.sqrt((goal_pose.pose.pose.position.x)**2 + (goal_pose.pose.pose.position.y)**2) |
| 120 | + current_distance = math.sqrt((self.pose.pose.pose.position.x-current_x)**2 + (self.pose.pose.pose.position.y-current_y)**2) |
| 121 | + |
| 122 | + #Publishing our vel_msg |
| 123 | + self.velocity_publisher.publish(vel_msg) |
| 124 | + self.rate.sleep() |
| 125 | + #Stopping our robot after the movement is over |
| 126 | + vel_msg.linear.x = 0 |
| 127 | + #vel_msg.angular.z = orientation - yaw |
| 128 | + #(temporary for testing purposes) |
| 129 | + # vel_msg.angular.z = 0 |
| 130 | + self.velocity_publisher.publish(vel_msg) |
| 131 | + |
| 132 | + rospy.spin() |
| 133 | + |
| 134 | +if __name__ == '__main__': |
| 135 | + |
| 136 | + while not rospy.is_shutdown(): |
| 137 | + |
| 138 | + #Testing our function |
| 139 | + |
| 140 | + x = gotoXY() |
| 141 | + x.move2goal() |
| 142 | + |
0 commit comments