Compare commits

...

59 Commits

Author SHA1 Message Date
90a1c03a5c :sparkles 2022-11-07 14:08:25 +01:00
30213107de :sparkles 2022-11-07 14:07:53 +01:00
78e76da161 :sparkles 2022-11-07 12:09:03 +01:00
1c79989840 :sparkles 2022-11-07 12:07:02 +01:00
90b5ff824d :sparkles 2022-11-07 12:06:27 +01:00
144551df39 2022-11-02 15:26:39 +01:00
e18767fcb6 2022-11-02 15:23:54 +01:00
919b7b2c4d 2022-11-02 15:22:35 +01:00
b30833dcae 2022-11-02 15:15:26 +01:00
12bcfe412f 2022-11-02 15:12:29 +01:00
374c321c4c 2022-11-02 15:08:31 +01:00
e974a0bb27 2022-11-02 15:05:39 +01:00
f7d459482a 2022-11-02 15:05:02 +01:00
073897c485 2022-11-02 15:01:03 +01:00
76a459fc9f 2022-11-02 14:58:55 +01:00
b0bd525726 2022-11-02 14:54:07 +01:00
c70da77fc9 2022-11-02 14:49:30 +01:00
60dbadabe1 2022-11-02 14:49:02 +01:00
bcf1ae2a5a 2022-11-02 14:46:59 +01:00
82e4c2eb43 2022-11-02 14:45:46 +01:00
02c2c04ca4 2022-11-02 14:43:44 +01:00
5fdcf1c0dc 2022-11-02 14:27:43 +01:00
71b7c67fff 2022-11-02 14:20:35 +01:00
fbd30c388c 2022-11-02 14:19:12 +01:00
ffe364dd97 2022-11-02 14:18:07 +01:00
21236301e0 2022-11-02 14:14:22 +01:00
9d8e95d711 2022-11-02 14:09:27 +01:00
22ef920735 2022-11-02 11:17:13 +01:00
0558fcd9e4 2022-11-02 11:16:22 +01:00
9890800079 2022-11-02 10:27:03 +01:00
d68039f09f 2022-11-02 10:26:30 +01:00
323185d08d 2022-11-02 10:19:05 +01:00
baed8628be 2022-11-02 10:12:59 +01:00
850ccb8179 2022-11-02 10:09:33 +01:00
879adf7b91 2022-10-31 15:48:50 +01:00
123c8fe350 2022-10-31 15:23:19 +01:00
f93a046270 2022-10-31 15:20:21 +01:00
9cc3b41f87 2022-10-31 15:12:38 +01:00
81862f8ee3 2022-10-31 15:07:58 +01:00
3219028980 2022-10-31 15:03:15 +01:00
cf21934931 2022-10-31 14:56:10 +01:00
a7616ad41c 2022-10-31 14:55:39 +01:00
963509fd8a 2022-10-31 14:53:58 +01:00
2c65a75f28 2022-10-31 14:50:11 +01:00
0621d02fff 2022-10-31 14:49:29 +01:00
51b29110bc 2022-10-31 14:48:20 +01:00
8984fcf6af 2022-10-31 14:45:43 +01:00
6c27ad4805 Quick fix for imports 2022-10-31 14:40:28 +01:00
437ccde0f1 2022-10-26 14:56:57 +02:00
e329d2b87f 2022-10-26 14:54:10 +02:00
679d6b78c5 2022-10-26 14:52:20 +02:00
302095a929 2022-10-26 14:50:59 +02:00
8be9656f5d 2022-10-26 14:45:06 +02:00
15fab9c09c 2022-10-26 14:43:48 +02:00
04c8dcc96e 2022-10-26 14:37:03 +02:00
5ddcd8499d 2022-10-26 14:34:57 +02:00
9145085739 2022-10-26 14:32:30 +02:00
ebf356445b 2022-10-26 14:30:18 +02:00
ef5f297a47 2022-10-26 14:30:13 +02:00
7 changed files with 178 additions and 70 deletions

View File

@ -52,6 +52,7 @@ def main():
angle = np.rad2deg(np.arctan(position[0]/position[2]))
drive_distance = np.sqrt(position[0]**2 + position[2]**2)
print(drive_distance)
if angle < 0:
arlo.go_diff(POWER, POWER, 0, 1)
sleep((abs(angle) * TURN_T)/1000)
@ -61,9 +62,9 @@ def main():
sleep((abs(angle) * TURN_T * CLOCKWISE_OFFSET)/1000)
arlo.stop()
arlo.go_diff(POWER, POWER + RIGHT_WHEEL_OFFSET, 1, 1)
sleep((drive_distance * DRIVE_T)/1000)
arlo.stop()
# arlo.go_diff(POWER, POWER + RIGHT_WHEEL_OFFSET, 1, 1)
# sleep((drive_distance * DRIVE_T)/1000)
# arlo.stop()
if __name__ == "__main__":

View File

@ -5,16 +5,16 @@ import cv2
import robot
LANDMARKS = [7,11,10,6] # SET ARUCO NUMBERS
LANDMARKS = [1,2,3,4] # SET ARUCO NUMBERS
POWER = 70
TURN_T = 7.9 # 1 degree
TURN_T = 8.3 # 1 degree
DRIVE_T = 22 # 1 centimeter
RIGHT_WHEEL_OFFSET = 4
RIGHT_WHEEL_OFFSET = 5
CLOCKWISE_OFFSET = 0.96
CLOCKWISE_OFFSET = 0.8
FOCAL_LENGTH = 1691
@ -38,21 +38,49 @@ def find_aruco(image):
return {ids[i][0]: box[0] for i, box in enumerate(corners)}
def careful_forward(drive_time, arlo, careful_range = 600):
def drunk_drive(drive_time, arlo, careful_range = 600):
start = time.time()
end = start + drive_time
turning = None
hit_something = False
while time.time() < end:
forward_dist = arlo.read_front_ping_sensor()
right_dist = arlo.read_right_ping_sensor()
left_dist = arlo.read_left_ping_sensor()
if forward_dist > careful_range and all(x > 400 for x in [right_dist, left_dist]):
if forward_dist > careful_range and all(x > 250 for x in [right_dist, left_dist]):
turning = None
arlo.go_diff(POWER, POWER + RIGHT_WHEEL_OFFSET, 1, 1)
else:
if turning == "R" or (forward_dist > careful_range and right_dist > 250 and turning is None):
arlo.go_diff(POWER, POWER, 1, 0)
turning = "R"
else:
arlo.go_diff(POWER, POWER + RIGHT_WHEEL_OFFSET, 0, 1)
turning = "L"
time.sleep(0.01)
def careful_forward(drive_time, arlo, careful_range = 600):
start = time.time()
if drive_time > 0.8:
drive_time = 0.8
hit_something = True
else:
hit_something = False
end = start + drive_time
turning = None
while time.time() < end:
forward_dist = arlo.read_front_ping_sensor()
right_dist = arlo.read_right_ping_sensor()
left_dist = arlo.read_left_ping_sensor()
if forward_dist > careful_range and all(x > 250 for x in [right_dist, left_dist]):
turning = None
arlo.go_diff(POWER, POWER + RIGHT_WHEEL_OFFSET, 1, 1)
else:
hit_something = True
if turning == "R" or (forward_dist > careful_range and right_dist > 400 and turning is None):
if turning == "R" or (forward_dist > careful_range and right_dist > 250 and turning is None):
arlo.go_diff(POWER, POWER, 1, 0)
turning = "R"
else:
@ -87,17 +115,15 @@ def main():
if landmark in arucos:
break
careful_forward(3, noah)
drunk_drive(3, noah)
position = cv2.aruco.estimatePoseSingleMarkers(
np.array([arucos[landmark]]), 14.5, CAMERA_MATRIX, DIST_COEF
)[1][0][0]
angle = np.rad2deg(np.arctan(position[0]/position[2]))
drive_distance = np.sqrt(position[0]**2 + position[2]**2) - 30
if drive_distance < 30:
break
angle = np.rad2deg(np.arctan(position[0]/position[2])) - 5
drive_distance = np.sqrt(position[0]**2 + position[2]**2) - 100
if angle < 0:
noah.go_diff(POWER, POWER, 0, 1)
@ -109,7 +135,20 @@ def main():
noah.stop()
if not careful_forward((drive_distance * DRIVE_T)/1000, noah, 400):
arucos = find_aruco(noah.take_photo())
if landmark in arucos:
position = cv2.aruco.estimatePoseSingleMarkers(
np.array([arucos[landmark]]), 14.5, CAMERA_MATRIX, DIST_COEF
)[1][0][0]
drive_distance = np.sqrt(position[0]**2 + position[2]**2) - 25
noah.go_diff(POWER, POWER, 1, 1)
time.sleep((drive_distance * DRIVE_T)/1000)
noah.stop()
break
if __name__ == "__main__":
start = time.time()
main()
print(f"Drove for {time.time() - start} seconds")

BIN
rally.zip Normal file

Binary file not shown.

111
rally2.py
View File

@ -7,18 +7,18 @@ from selflocalization import particle, camera
import robot
LANDMARKS = [7, 11, 10, 6]
LANDMARKS = [6,8,9,7]
LANDMARK_POSITIONS = {
7: [0, 0],
11: [200, 0],
10: [0, 300],
6: [200, 300]
6: [0, 0],
8: [300, 0],
9: [0, 400],
7: [300, 400]
}
POWER = 70
TURN_T = 9.1 # 1 degree
TURN_T = 9.6 # 1 degree
DRIVE_T = 22 # 1 centimeter
RIGHT_WHEEL_OFFSET = 4
@ -41,7 +41,9 @@ NUM_PARTICLES = 1000
def look_around(noah, particles, cam, est_pose):
for _ in range(24):
time.sleep(0.2)
# Fetch next frame
for _ in range(10):
colour = cam.get_next_frame()
landmark_values = []
@ -54,7 +56,7 @@ def look_around(noah, particles, cam, est_pose):
print(
"Object ID = ", objectIDs[i], ", Distance = ", dists[i], ", angle = ", angles[i])
if objectIDs[i] in LANDMARKS:
landmark_values.append((objectIDs[i], dists[i], angles[i]))
landmark_values.append((objectIDs[i], dists[i] + 22.5, angles[i]))
# Compute particle weights
for p in particles:
@ -79,7 +81,7 @@ def look_around(noah, particles, cam, est_pose):
time.sleep((15 * TURN_T)/1000)
noah.stop()
for p in particles:
p.setTheta(p.theta + np.deg2rad(15))
p.setTheta(p.theta - np.deg2rad(15))
# The estimate of the robots current pose
est_pose = particle.estimate_pose(particles)
@ -95,7 +97,7 @@ def turn_towards_landmark(noah, particles, est_pose, landmark):
angle = np.rad2deg(np.arctan(relative_pos[1]/relative_pos[0]))
turn_angle = np.mod(angle - (np.rad2deg(current_theta) - 180), 360)
for p in particles:
p.setTheta(p.theta + np.deg2rad(turn_angle))
p.setTheta(p.theta - np.deg2rad(turn_angle))
if turn_angle < 180:
noah.go_diff(POWER, POWER, 0, 1)
time.sleep((abs(turn_angle) * TURN_T)/1000)
@ -105,6 +107,7 @@ def turn_towards_landmark(noah, particles, est_pose, landmark):
time.sleep((abs(360 - turn_angle) * TURN_T * CLOCKWISE_OFFSET)/1000)
noah.stop()
particle.add_uncertainty(particles, SIGMA, SIGMA_THETA)
# The estimate of the robots current pose
est_pose = particle.estimate_pose(particles)
return particles, est_pose
@ -120,7 +123,7 @@ def time_to_landmark(est_pose, landmark):
return (DRIVE_T * drive_distance)/1000
def drive_until_stopped(noah):
def drive_until_stopped(noah, particles):
noah.go_diff(POWER, POWER+RIGHT_WHEEL_OFFSET, 1, 1)
start = time.time()
while True:
@ -136,10 +139,24 @@ def drive_until_stopped(noah):
if right_dist < 400:
noah.stop()
break
if time.time() - start > 5:
noah.stop()
break
time.sleep(0.01)
end = time.time()
return end - start
time_driven = end - start
distance_driven = (time_driven*1000)/DRIVE_T
for p in particles:
x = np.cos(p.theta) * distance_driven
y = np.sin(p.theta) * distance_driven
p.x = p.x + x
p.y = p.y + y
particle.add_uncertainty(particles, SIGMA, SIGMA_THETA)
est_pose = particle.estimate_pose(particles)
return time_driven, est_pose, particles
def drunk_drive(noah):
@ -164,7 +181,8 @@ def drunk_drive(noah):
time.sleep(0.01)
def inch_closer(noah):
def inch_closer(noah, particles):
start = time.time()
noah.go_diff(POWER, POWER+RIGHT_WHEEL_OFFSET, 1, 1)
while True:
forward_dist = noah.read_front_ping_sensor()
@ -172,6 +190,19 @@ def inch_closer(noah):
noah.stop()
break
end = time.time()
time_driven = end - start
distance_driven = (time_driven*1000)/DRIVE_T
for p in particles:
x = np.cos(p.theta) * distance_driven
y = np.sin(p.theta) * distance_driven
p.x = p.x + x
p.y = p.y + y
particle.add_uncertainty(particles, SIGMA, SIGMA_THETA)
est_pose = particle.estimate_pose(particles)
return est_pose, particles
def initialize_particles(num_particles):
particles = []
@ -217,33 +248,67 @@ def calc_weight(particle, landmark_values):
particle.setWeight(np.product(weights))
def turn_90_degrees(noah, est_pose, particles):
x_values = [i[0] for i in LANDMARK_POSITIONS.values()]
y_values = [i[1] for i in LANDMARK_POSITIONS.values()]
middle = np.array([max(x_values)/2, max(y_values)/2])
def main():
current_position = np.array([est_pose.x, est_pose.y])
relative_pos = middle - current_position
angle = np.arctan(relative_pos[1]/relative_pos[0])
relative_angle = np.mod(angle - est_pose.theta, 2.0*np.pi)
clockwise = relative_angle > 180
if clockwise:
noah.go_diff(POWER, POWER, 1, 0)
time.sleep((90 * TURN_T * CLOCKWISE_OFFSET)/1000)
else:
noah.go_diff(POWER, POWER, 0, 1)
time.sleep((90 * TURN_T)/1000)
noah.stop()
for p in particles:
if clockwise:
p.setTheta(p.theta - np.deg2rad(90))
else:
p.setTheta(p.theta + np.deg2rad(90))
particle.add_uncertainty(particles, SIGMA, SIGMA_THETA)
_, est_pose, particles = drive_until_stopped(noah, particles)
return est_pose, particles
def main(noah):
landmark_order = LANDMARKS + [
LANDMARKS[0]
]
cam = camera.Camera(0, 'arlo', useCaptureThread=True)
particles = initialize_particles(NUM_PARTICLES)
# The estimate of the robots current pose
est_pose = particle.estimate_pose(particles)
noah = robot.Robot() # Noah er vores robots navn
cam = camera.Camera(0, 'arlo', useCaptureThread=True)
for landmark in landmark_order:
print(f"Going to landmark {landmark}")
while True:
particles, est_pose = look_around(noah, particles, cam, est_pose)
particles, est_pose = turn_towards_landmark(
noah, particles, est_pose, landmark)
print(est_pose)
particles, est_pose = turn_towards_landmark(noah, particles, est_pose, landmark)
drive_time = time_to_landmark(est_pose, landmark)
if not abs(drive_until_stopped(noah) - drive_time) < 0.5:
drunk_drive(noah)
time_driven, est_pose, particles = drive_until_stopped(noah, particles)
if not abs(time_driven - drive_time) < 0.5:
# drunk_drive(noah)
est_pose, particles = turn_90_degrees(noah, est_pose, particles)
continue
inch_closer(noah)
est_pose, particles = inch_closer(noah, particles)
break
if __name__ == "__main__":
main()
noah = robot.Robot() # Noah er vores robots navn
try:
main(noah)
except KeyboardInterrupt:
noah.stop()

View File

@ -1,2 +1 @@
from .robot import Robot
from .arlo import Arlo

View File

@ -114,13 +114,14 @@ class Camera(object):
# Set camera calibration info
if robottype == 'arlo':
self.imageSize = (1280, 720)
focal_length = 1050
self.imageSize = (1024, 720)
#self.intrinsic_matrix = np.asarray([ 7.1305391967046853e+02, 0., 3.1172820723774367e+02, 0.,
# 7.0564929862291285e+02, 2.5634470978315028e+02, 0., 0., 1. ], dtype = np.float64)
#self.intrinsic_matrix = np.asarray([ 6.0727040957659040e+02, 0., 3.0757300398967601e+02, 0.,
# 6.0768864690145904e+02, 2.8935674612358201e+02, 0., 0., 1. ], dtype = np.float64)
self.intrinsic_matrix = np.asarray([500, 0., self.imageSize[0] / 2.0, 0.,
500, self.imageSize[1] / 2.0, 0., 0., 1.], dtype = np.float64)
self.intrinsic_matrix = np.asarray([focal_length, 0., self.imageSize[0] / 2.0, 0.,
focal_length, self.imageSize[1] / 2.0, 0., 0., 1.], dtype = np.float64)
self.intrinsic_matrix.shape = (3, 3)
#self.distortion_coeffs = np.asarray([ 1.1911006165076067e-01, -1.0003366233413549e+00,
# 1.9287903277399834e-02, -2.3728201444308114e-03, -2.8137265581326476e-01 ], dtype = np.float64)

View File

@ -37,6 +37,9 @@ class Particle(object):
def copy(self):
return Particle(self.x, self.y, self.theta, self.weight)
def __str__(self) -> str:
return f"({self.x},{self.y},{self.theta})"
def estimate_pose(particles_list):
"""Estimate the pose from particles by computing the average position and orientation over all particles.