|
| 1 | +# -------------- |
| 2 | +# User Instructions |
| 3 | +# |
| 4 | +# Define a function cte in the robot class that will |
| 5 | +# compute the crosstrack error for a robot on a |
| 6 | +# racetrack with a shape as described in the video. |
| 7 | +# |
| 8 | +# You will need to base your error calculation on |
| 9 | +# the robot's location on the track. Remember that |
| 10 | +# the robot will be traveling to the right on the |
| 11 | +# upper straight segment and to the left on the lower |
| 12 | +# straight segment. |
| 13 | +# |
| 14 | +# -------------- |
| 15 | +# Grading Notes |
| 16 | +# |
| 17 | +# We will be testing your cte function directly by |
| 18 | +# calling it with different robot locations and making |
| 19 | +# sure that it returns the correct crosstrack error. |
| 20 | + |
| 21 | +from math import * |
| 22 | +import random |
| 23 | +import sys |
| 24 | + |
| 25 | + |
| 26 | +# ------------------------------------------------ |
| 27 | +# |
| 28 | +# this is the robot class |
| 29 | +# |
| 30 | + |
| 31 | +class robot: |
| 32 | + |
| 33 | + # -------- |
| 34 | + # init: |
| 35 | + # creates robot and initializes location/orientation to 0, 0, 0 |
| 36 | + # |
| 37 | + |
| 38 | + def __init__(self, length = 20.0): |
| 39 | + self.x = 0.0 |
| 40 | + self.y = 0.0 |
| 41 | + self.orientation = 0.0 |
| 42 | + self.length = length |
| 43 | + self.steering_noise = 0.0 |
| 44 | + self.distance_noise = 0.0 |
| 45 | + self.steering_drift = 0.0 |
| 46 | + |
| 47 | + # -------- |
| 48 | + # set: |
| 49 | + # sets a robot coordinate |
| 50 | + # |
| 51 | + |
| 52 | + def set(self, new_x, new_y, new_orientation): |
| 53 | + |
| 54 | + self.x = float(new_x) |
| 55 | + self.y = float(new_y) |
| 56 | + self.orientation = float(new_orientation) % (2.0 * pi) |
| 57 | + |
| 58 | + |
| 59 | + # -------- |
| 60 | + # set_noise: |
| 61 | + # sets the noise parameters |
| 62 | + # |
| 63 | + |
| 64 | + def set_noise(self, new_s_noise, new_d_noise): |
| 65 | + # makes it possible to change the noise parameters |
| 66 | + # this is often useful in particle filters |
| 67 | + self.steering_noise = float(new_s_noise) |
| 68 | + self.distance_noise = float(new_d_noise) |
| 69 | + |
| 70 | + # -------- |
| 71 | + # set_steering_drift: |
| 72 | + # sets the systematical steering drift parameter |
| 73 | + # |
| 74 | + |
| 75 | + def set_steering_drift(self, drift): |
| 76 | + self.steering_drift = drift |
| 77 | + |
| 78 | + # -------- |
| 79 | + # move: |
| 80 | + # steering = front wheel steering angle, limited by max_steering_angle |
| 81 | + # distance = total distance driven, most be non-negative |
| 82 | + |
| 83 | + def move(self, steering, distance, |
| 84 | + tolerance = 0.001, max_steering_angle = pi / 4.0): |
| 85 | + |
| 86 | + if steering > max_steering_angle: |
| 87 | + steering = max_steering_angle |
| 88 | + if steering < -max_steering_angle: |
| 89 | + steering = -max_steering_angle |
| 90 | + if distance < 0.0: |
| 91 | + distance = 0.0 |
| 92 | + |
| 93 | + |
| 94 | + # make a new copy |
| 95 | + res = robot() |
| 96 | + res.length = self.length |
| 97 | + res.steering_noise = self.steering_noise |
| 98 | + res.distance_noise = self.distance_noise |
| 99 | + res.steering_drift = self.steering_drift |
| 100 | + |
| 101 | + # apply noise |
| 102 | + steering2 = random.gauss(steering, self.steering_noise) |
| 103 | + distance2 = random.gauss(distance, self.distance_noise) |
| 104 | + |
| 105 | + # apply steering drift |
| 106 | + steering2 += self.steering_drift |
| 107 | + |
| 108 | + # Execute motion |
| 109 | + turn = tan(steering2) * distance2 / res.length |
| 110 | + |
| 111 | + if abs(turn) < tolerance: |
| 112 | + |
| 113 | + # approximate by straight line motion |
| 114 | + |
| 115 | + res.x = self.x + (distance2 * cos(self.orientation)) |
| 116 | + res.y = self.y + (distance2 * sin(self.orientation)) |
| 117 | + res.orientation = (self.orientation + turn) % (2.0 * pi) |
| 118 | + |
| 119 | + else: |
| 120 | + |
| 121 | + # approximate bicycle model for motion |
| 122 | + |
| 123 | + radius = distance2 / turn |
| 124 | + cx = self.x - (sin(self.orientation) * radius) |
| 125 | + cy = self.y + (cos(self.orientation) * radius) |
| 126 | + res.orientation = (self.orientation + turn) % (2.0 * pi) |
| 127 | + res.x = cx + (sin(res.orientation) * radius) |
| 128 | + res.y = cy - (cos(res.orientation) * radius) |
| 129 | + |
| 130 | + return res |
| 131 | + |
| 132 | + |
| 133 | + |
| 134 | + |
| 135 | + def __repr__(self): |
| 136 | + return '[x=%.5f y=%.5f orient=%.5f]' % (self.x, self.y, self.orientation) |
| 137 | + |
| 138 | + |
| 139 | +############## ONLY ADD / MODIFY CODE BELOW THIS LINE #################### |
| 140 | + |
| 141 | + def cte(self, radius): |
| 142 | + # |
| 143 | + # |
| 144 | + # Add code here |
| 145 | + # |
| 146 | + # |
| 147 | + |
| 148 | + return cte |
| 149 | + |
| 150 | +############## ONLY ADD / MODIFY CODE ABOVE THIS LINE #################### |
| 151 | + |
| 152 | + |
| 153 | + |
| 154 | + |
0 commit comments