test_longitudinal.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #!/usr/bin/env python3
  2. import itertools
  3. import unittest
  4. from parameterized import parameterized_class
  5. from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import STOP_DISTANCE
  6. from openpilot.selfdrive.test.longitudinal_maneuvers.maneuver import Maneuver
  7. # TODO: make new FCW tests
  8. def create_maneuvers(kwargs):
  9. maneuvers = [
  10. Maneuver(
  11. 'approach stopped car at 25m/s, initial distance: 120m',
  12. duration=20.,
  13. initial_speed=25.,
  14. lead_relevancy=True,
  15. initial_distance_lead=120.,
  16. speed_lead_values=[30., 0.],
  17. breakpoints=[0., 1.],
  18. **kwargs,
  19. ),
  20. Maneuver(
  21. 'approach stopped car at 20m/s, initial distance 90m',
  22. duration=20.,
  23. initial_speed=20.,
  24. lead_relevancy=True,
  25. initial_distance_lead=90.,
  26. speed_lead_values=[20., 0.],
  27. breakpoints=[0., 1.],
  28. **kwargs,
  29. ),
  30. Maneuver(
  31. 'steady state following a car at 20m/s, then lead decel to 0mph at 1m/s^2',
  32. duration=50.,
  33. initial_speed=20.,
  34. lead_relevancy=True,
  35. initial_distance_lead=35.,
  36. speed_lead_values=[20., 20., 0.],
  37. breakpoints=[0., 15., 35.0],
  38. **kwargs,
  39. ),
  40. Maneuver(
  41. 'steady state following a car at 20m/s, then lead decel to 0mph at 2m/s^2',
  42. duration=50.,
  43. initial_speed=20.,
  44. lead_relevancy=True,
  45. initial_distance_lead=35.,
  46. speed_lead_values=[20., 20., 0.],
  47. breakpoints=[0., 15., 25.0],
  48. **kwargs,
  49. ),
  50. Maneuver(
  51. 'steady state following a car at 20m/s, then lead decel to 0mph at 3m/s^2',
  52. duration=50.,
  53. initial_speed=20.,
  54. lead_relevancy=True,
  55. initial_distance_lead=35.,
  56. speed_lead_values=[20., 20., 0.],
  57. breakpoints=[0., 15., 21.66],
  58. **kwargs,
  59. ),
  60. Maneuver(
  61. 'steady state following a car at 20m/s, then lead decel to 0mph at 3+m/s^2',
  62. duration=40.,
  63. initial_speed=20.,
  64. lead_relevancy=True,
  65. initial_distance_lead=35.,
  66. speed_lead_values=[20., 20., 0.],
  67. prob_lead_values=[0., 1., 1.],
  68. cruise_values=[20., 20., 20.],
  69. breakpoints=[2., 2.01, 8.8],
  70. **kwargs,
  71. ),
  72. Maneuver(
  73. "approach stopped car at 20m/s, with prob_lead_values",
  74. duration=30.,
  75. initial_speed=20.,
  76. lead_relevancy=True,
  77. initial_distance_lead=120.,
  78. speed_lead_values=[0.0, 0., 0.],
  79. prob_lead_values=[0.0, 0., 1.],
  80. cruise_values=[20., 20., 20.],
  81. breakpoints=[0.0, 2., 2.01],
  82. **kwargs,
  83. ),
  84. Maneuver(
  85. "approach slower cut-in car at 20m/s",
  86. duration=20.,
  87. initial_speed=20.,
  88. lead_relevancy=True,
  89. initial_distance_lead=50.,
  90. speed_lead_values=[15., 15.],
  91. breakpoints=[1., 11.],
  92. only_lead2=True,
  93. **kwargs,
  94. ),
  95. Maneuver(
  96. "stay stopped behind radar override lead",
  97. duration=20.,
  98. initial_speed=0.,
  99. lead_relevancy=True,
  100. initial_distance_lead=10.,
  101. speed_lead_values=[0., 0.],
  102. prob_lead_values=[0., 0.],
  103. breakpoints=[1., 11.],
  104. only_radar=True,
  105. **kwargs,
  106. ),
  107. Maneuver(
  108. "NaN recovery",
  109. duration=30.,
  110. initial_speed=15.,
  111. lead_relevancy=True,
  112. initial_distance_lead=60.,
  113. speed_lead_values=[0., 0., 0.0],
  114. breakpoints=[1., 1.01, 11.],
  115. cruise_values=[float("nan"), 15., 15.],
  116. **kwargs,
  117. ),
  118. Maneuver(
  119. 'cruising at 25 m/s while disabled',
  120. duration=20.,
  121. initial_speed=25.,
  122. lead_relevancy=False,
  123. enabled=False,
  124. **kwargs,
  125. ),
  126. ]
  127. if not kwargs['force_decel']:
  128. # controls relies on planner commanding to move for stock-ACC resume spamming
  129. maneuvers.append(Maneuver(
  130. "resume from a stop",
  131. duration=20.,
  132. initial_speed=0.,
  133. lead_relevancy=True,
  134. initial_distance_lead=STOP_DISTANCE,
  135. speed_lead_values=[0., 0., 2.],
  136. breakpoints=[1., 10., 15.],
  137. ensure_start=True,
  138. **kwargs,
  139. ))
  140. return maneuvers
  141. @parameterized_class(("e2e", "force_decel"), itertools.product([True, False], repeat=2))
  142. class LongitudinalControl(unittest.TestCase):
  143. e2e: bool
  144. force_decel: bool
  145. def test_maneuver(self):
  146. for maneuver in create_maneuvers({"e2e": self.e2e, "force_decel": self.force_decel}):
  147. with self.subTest(title=maneuver.title, e2e=maneuver.e2e, force_decel=maneuver.force_decel):
  148. print(maneuver.title, f'in {"e2e" if maneuver.e2e else "acc"} mode')
  149. valid, _ = maneuver.evaluate()
  150. self.assertTrue(valid)
  151. if __name__ == "__main__":
  152. unittest.main(failfast=True)