-
Notifications
You must be signed in to change notification settings - Fork 6
/
utils.py
95 lines (83 loc) · 2.92 KB
/
utils.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
''' Common functions used in this library.
'''
import skimage.io
import skimage.morphology as skim
import io
import numpy as np
try:
from ompl import base as ob
from ompl import geometric as og
from ompl import util as ou
except ImportError:
raise ImportError("Container does not have OMPL installed")
def png_decoder(key, value):
'''
PNG decoder with gray images.
:param key:
:param value:
'''
if not key.endswith(".png"):
return None
assert isinstance(value, bytes)
return skimage.io.imread(io.BytesIO(value), as_gray=True)
def cls_decoder(key, value):
'''
Converts class represented as bytes to integers.
:param key:
:param value:
:returns the decoded value
'''
if not key.endswith(".cls"):
return None
assert isinstance(value, bytes)
return int(value)
def geom2pix(pos, res=0.05, size=(480, 480)):
"""
Convert geometrical position to pixel co-ordinates. The origin
is assumed to be at [image_size[0]-1, 0].
:param pos: The (x,y) geometric co-ordinates.
:param res: The distance represented by each pixel.
:param size: The size of the map image
:returns (int, int): The associated pixel co-ordinates.
NOTE: The Pixel co-ordinates are represented as follows:
(0,0)------ X ----------->|
| |
| |
| |
| |
Y |
| |
| |
v |
---------------------------
"""
return (np.int(np.floor(pos[0]/res)), np.int(size[0]-1-np.floor(pos[1]/res)))
class ValidityChecker(ob.StateValidityChecker):
'''A class to check if an obstacle is in collision or not.
'''
def __init__(self, si, CurMap, MapMask=None, res=0.05, robot_radius=0.1):
'''
Intialize the class object, with the current map and mask generated
from the transformer model.
:param si: an object of type ompl.base.SpaceInformation
:param CurMap: A np.array with the current map.
:param MapMask: Areas of the map to be masked.
'''
super().__init__(si)
self.size = CurMap.shape
# Dilate image for collision checking
InvertMap = np.abs(1-CurMap)
InvertMapDilate = skim.dilation(InvertMap, skim.disk(robot_radius/res))
MapDilate = abs(1-InvertMapDilate)
if MapMask is None:
self.MaskMapDilate = MapDilate>0.5
else:
self.MaskMapDilate = np.logical_and(MapDilate, MapMask)
def isValid(self, state):
'''
Check if the given state is valid.
:param state: An ob.State object to be checked.
:returns bool: True if the state is valid.
'''
pix_dim = geom2pix(state, size=self.size)
return self.MaskMapDilate[pix_dim[1], pix_dim[0]]