-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmttt.py
105 lines (76 loc) · 3.33 KB
/
mttt.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
#!/usr/bin/env python
"""
M2020 Terrain Traversability analysis Tools (MTTT) velocity function
Based on Ono et al. (2018). See Figure 5 for velocity model
Authors: Olivier Lamarre
Affl.: STARS Laboratory, University of Toronto
"""
import logging
import numpy as np
from gplanetary_nav.site.loader import SiteLoader
from gplanetary_nav.cost.base_cost import BaseCost
log = logging.getLogger(__name__)
class MTTTVelocity(BaseCost):
def __init__(self, site: SiteLoader, rover_cfg: dict, optimistic: bool=False):
"""Init MTTT velocity model
Args:
site: site instance
rover_cfg: rover configuration dictionary
optimistic: use the fastest velocity estimates instead of the
slowest ones.
"""
super().__init__(site, rover_cfg, optimistic=optimistic)
def eval(self, node, pitch, roll, length, duration=None) -> float:
"""Time duration to cross an edge segment
Args:
(See BaseCost.eval for full documentation)
Return:
traverse duration, in seconds
"""
# Implementation of Figure 5 in Ono et al. (2018)
# Note that terrain class indexing starts at 0 in this implementation
if self.site.terrain[node] == 0: # Terrain class 1 in paper
if (self.site.slope[node] <= np.deg2rad(15) and
self.site.cfa[node] <= 0.07):
return length/64.8*3600
elif ( self.site.slope[node] <= np.deg2rad(20) and
self.site.cfa[node] <= 0.15):
return length/52.5*3600
elif ( self.site.slope[node] <= np.deg2rad(25) and
self.site.cfa[node] <= 0.15):
return length/10.9*3600
else:
return np.inf
elif self.site.terrain[node] == 1: # Terrain class 2 in paper
if (self.site.slope[node] <= np.deg2rad(20) and
self.site.cfa[node] <= 0.15):
if self.optimistic:
return length/48.5*3600
else:
return length/24.2*3600
elif ( self.site.slope[node] <= np.deg2rad(25) and
self.site.cfa[node] <= 0.15):
return length/10.9*3600
else:
return np.inf
elif self.site.terrain[node] == 2: # Terrain class 3 in paper
if (self.site.slope[node] <= np.deg2rad(10) and
self.site.cfa[node] <= 0.15):
if self.optimistic:
return length/40.8*3600
else:
return length/10.9*3600
else:
return np.inf
elif self.site.terrain[node] == 3: # Terrain class 4 in paper
if (self.site.slope[node] <= np.deg2rad(10) and
self.site.cfa[node] <= 0.15):
return length/10.9*3600
else:
return np.inf
elif self.site.terrain[node] in [4,255]: # Terrain class 5 in paper
return np.inf
else:
raise ValueError(
f"Invalid MTTT terrain class: {self.site.terrain[node]} "
f"(only expects terrain classes 0,1,2,3,4,255)")