forked from robotika/eduro
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathray_trace.py
More file actions
55 lines (43 loc) · 1.59 KB
/
ray_trace.py
File metadata and controls
55 lines (43 loc) · 1.59 KB
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
#!/usr/bin/env python
"""
RayTrace for MonteCarloLocalisation
"""
# instead of line with start/end it could be rewritten for simply ((x1,y1),(x2,y2))
import math
from line import distance
def normalizeAnglePIPI( angle ):
"normalize only within 2PI error"
if angle < -math.pi:
angle += 2*math.pi
if angle > math.pi:
angle -= 2*math.pi
return angle
def combinedPose( robotPose, sensorPose ):
return (
robotPose[0] + sensorPose[0] * math.cos( robotPose[2] ) - sensorPose[1] * math.sin( robotPose[2] ),
robotPose[1] + sensorPose[0] * math.sin( robotPose[2] ) + sensorPose[1] * math.cos( robotPose[2] ),
normalizeAnglePIPI( robotPose[2] + sensorPose[2] ) )
def rayTraceSingleLine( pose, wallStart, wallEnd, maxRadius ):
a = wallStart[1] - wallEnd[1]
b = wallEnd[0] - wallStart[0]
c = - a * wallStart[0] - b * wallStart[1]
frac = a * math.cos( pose[2] ) + b * math.sin( pose[2] )
if math.fabs( frac ) < 0.0001:
return maxRadius
t = -(a * pose[0] + b * pose[1] + c)/frac;
if t < 0:
return maxRadius
# check that crossing belongs to the wall and is not outside
crossing = ( pose[0] + t * math.cos( pose[2] ), pose[1] + t * math.sin( pose[2] ) )
if distance( crossing, wallStart ) + distance( crossing, wallEnd ) > distance( wallStart, wallEnd ) + 0.01:
return maxRadius
return t < maxRadius and t or maxRadius
def rayTrace( pose, obstacles, maxRadius = 1000 ):
"return distance to nearest obstacle"
dist = maxRadius
for obj in obstacles:
a = obj[0]
for b in obj[1:]:
dist = rayTraceSingleLine( pose, a, b, dist )
a = b
return dist