Source code for leads_emulation
from random import randint as _randint
from time import time as _time
from typing import override as _override
from numpy import sin as _sin, pi as _pi
from leads import Controller as _Controller, DataContainer as _DataContainer
[docs]
class _EmulatedController(_Controller):
def __init__(self, minimum: int = 30, maximum: int = 40, skid_possibility: float = .1) -> None:
super().__init__()
self.minimum: int = minimum
self.maximum: int = maximum
self.skid_possibility: float = skid_possibility
self._last_speed: float = 0
self._last_time: float = _time()
self._max_throttle: float = 0
self._max_brake: float = 0
[docs]
def generate_rear_wheel_speed(self, front_wheel_speed: float) -> float:
return front_wheel_speed if self.skid_possibility <= 0 else front_wheel_speed + int(_randint(
-int(1 / self.skid_possibility), int(1 / self.skid_possibility)) * self.skid_possibility)
[docs]
def generate_forward_acceleration(self, speed: float) -> float:
t = _time()
try:
return (speed - self._last_speed) / 3.6 / (t - self._last_time)
finally:
self._last_speed = speed
self._last_time = t
[docs]
def generate_throttle(self, forward_acceleration: float) -> float:
if forward_acceleration <= 0:
return 0
if forward_acceleration > self._max_throttle:
self._max_throttle = forward_acceleration
return forward_acceleration / self._max_throttle
[docs]
def generate_brake(self, forward_acceleration: float) -> float:
if forward_acceleration >= 0:
return 0
if (forward_acceleration := -forward_acceleration) > self._max_brake:
self._max_brake = forward_acceleration
return forward_acceleration / self._max_brake
[docs]
class RandomController(_EmulatedController):
[docs]
@_override
def read(self) -> _DataContainer:
return _DataContainer(voltage=48.0,
speed=(fws := _randint(self.minimum, self.maximum)),
front_wheel_speed=fws,
rear_wheel_speed=self.generate_rear_wheel_speed(fws),
forward_acceleration=(fa := self.generate_forward_acceleration(fws)),
gps_valid=True,
gps_ground_speed=fws,
latitude=_randint(4315, 4415) / 100,
longitude=-_randint(7888, 7988) / 100,
throttle=self.generate_throttle(fa),
brake=self.generate_brake(fa))
[docs]
class SinController(_EmulatedController):
def __init__(self, minimum: int = 30, maximum: int = 40, skid_possibility: float = .1,
acceleration: float = .01) -> None:
super().__init__(minimum, maximum, skid_possibility)
self.acceleration: float = acceleration
self.magnitude: int = int((maximum - minimum) * .5)
self.counter: float = 0
[docs]
@_override
def read(self) -> _DataContainer:
try:
return _DataContainer(voltage=48.0,
speed=(fws := (_sin(self.counter) * self.magnitude + self.magnitude)),
front_wheel_speed=fws,
rear_wheel_speed=self.generate_rear_wheel_speed(fws),
forward_acceleration=(fa := self.generate_forward_acceleration(fws)),
gps_valid=True,
gps_ground_speed=fws,
latitude=_randint(4315, 4415) / 100,
longitude=-_randint(7888, 7988) / 100,
throttle=self.generate_throttle(fa),
brake=self.generate_brake(fa))
finally:
self.counter = (self.counter + self.acceleration) % (2 * _pi)