mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-08 05:23:41 +08:00
6d742eb343
Add control trace and platform qualification tools that exercise explicit safety modes and vehicle coverage. Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> Co-authored-by: Dom <168790843+firestar5683@users.noreply.github.com> Co-authored-by: Kacper Rączy <gfw.kra@gmail.com> Co-authored-by: YassineYousfi <yyousfi1@binghamton.edu> Co-authored-by: firestarsdog <229254897+firestarsdog@users.noreply.github.com> Co-authored-by: dirwin31 <83434411+dirwin31@users.noreply.github.com> Co-authored-by: prabhaavp <prabhaav@msu.edu>
58 lines
2.2 KiB
Python
58 lines
2.2 KiB
Python
import math
|
|
import random
|
|
import struct
|
|
import unittest
|
|
import warnings
|
|
|
|
import numpy as np
|
|
|
|
from openpilot.common.scalar_clip import clip_scalar
|
|
|
|
|
|
class TestScalarClip(unittest.TestCase):
|
|
def compare(self, value, lower, upper):
|
|
results = []
|
|
for function in (lambda v, lo, hi: float(np.clip(v, lo, hi)), clip_scalar):
|
|
with warnings.catch_warnings(record=True) as seen:
|
|
warnings.simplefilter('always')
|
|
try:
|
|
result = ('value', struct.pack('>d', function(value, lower, upper)))
|
|
except Exception as error:
|
|
result = ('error', type(error), str(error))
|
|
results.append((result, [(warning.category, str(warning.message)) for warning in seen]))
|
|
self.assertEqual(results[0], results[1], (value, lower, upper))
|
|
|
|
def test_binary64_inputs_match_numpy_exactly(self):
|
|
randomizer = random.Random(20261015)
|
|
def finite():
|
|
while True:
|
|
value = struct.unpack('>d', randomizer.getrandbits(64).to_bytes(8, 'big'))[0]
|
|
if math.isfinite(value):
|
|
return value
|
|
for _ in range(3000):
|
|
lower, upper = sorted((finite(), finite()))
|
|
value = finite()
|
|
self.compare(value, lower, upper)
|
|
self.compare(np.float64(value), lower, upper)
|
|
|
|
def test_boundary_bits_and_nonfinite_inputs(self):
|
|
values = (-0.0, 0.0, -math.ulp(0.0), math.ulp(0.0), -1.0, 1.0,
|
|
math.nextafter(1.0, -math.inf), math.nextafter(1.0, math.inf),
|
|
-math.inf, math.inf, math.nan)
|
|
bounds = ((-1.0, 1.0), (-0.0, 1.0), (0.0, 1.0), (-1.0, -0.0), (-1.0, 0.0),
|
|
(-0.0, 0.0), (0.0, -0.0), (1.0, 1.0), (1.0, -1.0),
|
|
(-math.inf, math.inf), (math.nan, 1.0), (-1.0, math.nan))
|
|
for lower, upper in bounds:
|
|
for value in values:
|
|
self.compare(value, lower, upper)
|
|
self.compare(np.float64(value), lower, upper)
|
|
|
|
def test_other_types_keep_numpy_results_errors_and_warnings(self):
|
|
class FloatSubclass(float):
|
|
pass
|
|
values = (0, True, None, '0', np.float32(0.2), np.int64(2), FloatSubclass(0.2),
|
|
np.array(0.2), np.array([0.2]), np.array([0.2, 0.5]))
|
|
for value in values:
|
|
for lower, upper in ((-1.0, 1.0), (-1, 1), (np.float32(-1), np.float32(1))):
|
|
self.compare(value, lower, upper)
|