-
Notifications
You must be signed in to change notification settings - Fork 32
/
time.py
203 lines (172 loc) · 4.74 KB
/
time.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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
from __future__ import absolute_import
from __future__ import division
from math import ceil
class Time(object):
"""
Time class like in Gazebo. Unlike Gazebo's though, we always
use a positive number of nanoseconds, offset from a negative
or positive number of seconds.
"""
def __init__(self, sec=None, nsec=None, dbl=None, msg=None):
"""
:return:
"""
self.sec = 0
self.nsec = 0
self.set(sec, nsec, dbl, msg)
def set(self, sec=None, nsec=None, dbl=None, msg=None):
"""
Sets the time from either factor
:param sec: Number of seconds
:param nsec: Number of nanoseconds
:param dbl: Double / float time value
:param msg: Gazebo `Time` message
:return:
"""
if dbl is not None:
self.sec = int(dbl)
self.nsec = int(round((dbl - self.sec) * 10e9))
elif msg:
self.sec = msg.sec
self.nsec = msg.nsec
else:
if sec is not None:
self.sec = int(sec)
if nsec is not None:
self.nsec = int(nsec)
self._correct()
def _correct(self):
"""
Corrects overflowing nanoseconds
:return:
"""
if self.nsec < 0:
n = ceil(abs(self.nsec / float(10e9)))
self.sec -= n
self.nsec += n * 10e9
elif self.nsec >= 10e9:
n = int(self.nsec / 10e9)
self.sec += n
self.nsec -= n * 10e9
def is_zero(self):
"""
Check if this time is zero.
:return:
"""
return self.sec == 0 and self.nsec == 0
def __eq__(self, other):
"""
:param other:
:return:
"""
if isinstance(other, Time):
return self.sec == other.sec and self.nsec == other.nsec
else:
return Time(dbl=other) == self
def __hash__(self, other):
return hash(other)
def __ne__(self, other):
"""
Inequality.
:param other:
:return:
"""
return not self.__eq__(other)
def __gt__(self, other):
"""
Greater than
:param other:
:return:
"""
return float(self) > float(other)
def __lt__(self, other):
"""
Smaller than
:param other:
:return:
"""
return float(self) < float(other)
def __ge__(self, other):
"""
Greater than or equal to
:param other:
:return:
"""
return float(self) >= float(other)
def __le__(self, other):
"""
Less than or equal to
:param other:
:return:
"""
return float(self) <= float(other)
def __add__(self, other):
"""
Add two times
:param other:
:return:
"""
if isinstance(other, Time):
return self.__class__(
sec=self.sec + other.sec,
nsec=self.nsec + other.nsec)
# Otherwise assume a number
return self.__class__(dbl=float(self) + other)
__radd__ = __add__
def __sub__(self, other):
"""
Subtract two times
:param other:
:return:
"""
if isinstance(other, Time):
return self.__class__(
sec=self.sec - other.sec,
nsec=self.nsec - other.nsec)
# Assume a number
return self.__class__(dbl=float(self) - other)
def __rsub__(self, other):
"""
:param other:
:return:
"""
# This would only be called if `other` is not a Time instance,
# so assume the number version.
return self.__class__(dbl=other - float(self))
def __iadd__(self, other):
"""
Internal add
:param other:
:return:
"""
if isinstance(other, Time):
self.set(self.sec + other.sec, self.nsec + other.nsec)
else:
self.set(dbl=float(self) + other)
return self
def __isub__(self, other):
"""
Internal subtract
:param other:
:return:
"""
if isinstance(other, Time):
self.set(self.sec - other.sec, self.nsec - other.nsec)
else:
self.set(dbl=float(self) - other)
return self
def __neg__(self):
"""
Negative of this time value
:return:
"""
return self.__class__(-self.sec, -self.nsec)
def __float__(self):
"""
Float / double representation of this time
:return:
"""
return self.sec + self.nsec / 10.0e9
def __str__(self):
return "{}".format(float(self))
__repr__ = __str__