Path: blob/master/experiments/slamekf.py
1700 views
# -*- coding: utf-8 -*-1"""2Created on Sun Oct 9 08:25:01 201634@author: roger5"""67import numpy as np8910class WorldMap(object):1112def __init__(self, N=100):1314self.N = N15pass1617181920def measurements(self, x, theta):21""" return array of measurements (range, angle) if robot is in position22x"""2324N = 1025a = np.linspace(-np.pi, np.pi, self.N)26return a27282930def get_line(start, end):31"""Bresenham's Line Algorithm32Produces a list of tuples from start and end3334>>> points1 = get_line((0, 0), (3, 4))35>>> points2 = get_line((3, 4), (0, 0))36>>> assert(set(points1) == set(points2))37>>> print points138[(0, 0), (1, 1), (1, 2), (2, 3), (3, 4)]39>>> print points240[(3, 4), (2, 3), (1, 2), (1, 1), (0, 0)]4142source:43http://www.roguebasin.com/index.php?title=Bresenham%27s_Line_Algorithm44"""45# Setup initial conditions46x1, y1 = int(round(start[0])), int(round(start[1]))47x2, y2 = int(round(end[0])), int(round(end[1]))48dx = x2 - x149dy = y2 - y15051# Determine how steep the line is52is_steep = abs(dy) > abs(dx)5354# Rotate line55if is_steep:56x1, y1 = y1, x157x2, y2 = y2, x25859# Swap start and end points if necessary and store swap state60swapped = False61if x1 > x2:62x1, x2 = x2, x163y1, y2 = y2, y164swapped = True65# Recalculate differentials66dx = x2 - x167dy = y2 - y16869# Calculate error70error = int(dx / 2.0)71ystep = 1 if y1 < y2 else -17273# Iterate over bounding box generating points between start and end74y = y175points = []76for x in range(x1, x2 + 1):77coord = (y, x) if is_steep else (x, y)78points.append(coord)79error -= abs(dy)80if error < 0:81y += ystep82error += dx8384# Reverse the list if the coordinates were swapped85if swapped:86points.reverse()87return points888990world = np.zeros((1000,1000), dtype=bool)919293def add_line(p0, p1):94pts = get_line(p0, p1)95for p in pts:96try:97world[p[0], p[1]] = True98except:99pass # ignore out of range100101102add_line((0,0), (1000, 0))103104def measure(x, theta):105106dx,dy = world.shape107h = np.sqrt(2*(dx*dx + dy+dy))108p1 = [h*np.cos(theta), h*np.sin(theta)]109110111hits = get_line(x, p1)112113try:114for pt in hits:115if world[pt[0], pt[1]]:116return pt117except:118return -1119return -2120121122123124measure([100,100], -np.pi/2)125126127