forked from rlabbe/Kalman-and-Bayesian-Filters-in-Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
slamekf.py
125 lines (88 loc) · 2.58 KB
/
slamekf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# -*- coding: utf-8 -*-
"""
Created on Sun Oct 9 08:25:01 2016
@author: roger
"""
import numpy as np
class WorldMap(object):
def __init__(self, N=100):
self.N = N
pass
def measurements(self, x, theta):
""" return array of measurements (range, angle) if robot is in position
x"""
N = 10
a = np.linspace(-np.pi, np.pi, self.N)
return a
def get_line(start, end):
"""Bresenham's Line Algorithm
Produces a list of tuples from start and end
>>> points1 = get_line((0, 0), (3, 4))
>>> points2 = get_line((3, 4), (0, 0))
>>> assert(set(points1) == set(points2))
>>> print points1
[(0, 0), (1, 1), (1, 2), (2, 3), (3, 4)]
>>> print points2
[(3, 4), (2, 3), (1, 2), (1, 1), (0, 0)]
source:
http://www.roguebasin.com/index.php?title=Bresenham%27s_Line_Algorithm
"""
# Setup initial conditions
x1, y1 = int(round(start[0])), int(round(start[1]))
x2, y2 = int(round(end[0])), int(round(end[1]))
dx = x2 - x1
dy = y2 - y1
# Determine how steep the line is
is_steep = abs(dy) > abs(dx)
# Rotate line
if is_steep:
x1, y1 = y1, x1
x2, y2 = y2, x2
# Swap start and end points if necessary and store swap state
swapped = False
if x1 > x2:
x1, x2 = x2, x1
y1, y2 = y2, y1
swapped = True
# Recalculate differentials
dx = x2 - x1
dy = y2 - y1
# Calculate error
error = int(dx / 2.0)
ystep = 1 if y1 < y2 else -1
# Iterate over bounding box generating points between start and end
y = y1
points = []
for x in range(x1, x2 + 1):
coord = (y, x) if is_steep else (x, y)
points.append(coord)
error -= abs(dy)
if error < 0:
y += ystep
error += dx
# Reverse the list if the coordinates were swapped
if swapped:
points.reverse()
return points
world = np.zeros((1000,1000), dtype=bool)
def add_line(p0, p1):
pts = get_line(p0, p1)
for p in pts:
try:
world[p[0], p[1]] = True
except:
pass # ignore out of range
add_line((0,0), (1000, 0))
def measure(x, theta):
dx,dy = world.shape
h = np.sqrt(2*(dx*dx + dy+dy))
p1 = [h*np.cos(theta), h*np.sin(theta)]
hits = get_line(x, p1)
try:
for pt in hits:
if world[pt[0], pt[1]]:
return pt
except:
return -1
return -2
measure([100,100], -np.pi/2)